相同校验逻辑不同异常信息,如何减少Web服务接口代码冗余?
方案一:提取公共校验方法,传递错误消息参数
最直接的方式是把重复的校验逻辑抽成独立的公共方法,将不同接口需要的错误提示信息作为参数传入。这样公共逻辑只需要维护一次,不同接口调用时传入各自的错误文案即可。
比如针对clientId和clientName的校验,抽成如下公共方法:
// 公共校验clientId的方法 private void validateClientId(String clientId, String parseErrorMsg, String notExistErrorMsg) { Long id; try { id = Long.parseLong(clientId); } catch (NumberFormatException e) { throw new InterfaceException(parseErrorMsg); } if (!isClientIdExistInDB(id)) { // 假设这是你封装的DB查询方法 throw new InterfaceException(notExistErrorMsg); } } // 公共校验clientName的方法 private void validateClientName(String clientName, String notFoundErrorMsg) { if (!isClientNameExistInDB(clientName.toUpperCase())) { // 封装的DB查询方法 throw new InterfaceException(notFoundErrorMsg); } }
原来的两个接口校验方法可以简化为:
private void checkInterfaceA(String clientId, String clientName, ...) { validateClientId(clientId, "[EOS_E01] 'companyAClient.id' is empty.", "[EOS_E02] 'companyAClient.id' not match with DB records."); validateClientName(clientName, "[EOS_E03] 'companyAClient.name' not match with DB records."); // 接口A专属校验逻辑 } private void checkInterfaceB(String clientId, String clientName, ...) { validateClientId(clientId, "[E_XML_001] Parse Client ID error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/ID'.", "[E_XML_002] Client ID not found error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/ID'"); validateClientName(clientName, "[E_XML_003] Client name not found error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/NAME'"); // 接口B专属校验逻辑 }
方案二:用策略模式封装错误消息(扩展性更强)
如果后续还有更多接口需要类似校验,或者错误消息需要统一管理,可以定义一个错误消息提供者接口,每个接口实现自己的消息配置:
// 定义消息提供者接口 interface ValidationMessageProvider { String getClientIdParseErrorMsg(); String getClientIdNotExistErrorMsg(); String getClientNameNotFoundErrorMsg(); // 其他字段的错误消息方法... } // 接口A的消息提供者实现 class InterfaceAMessageProvider implements ValidationMessageProvider { @Override public String getClientIdParseErrorMsg() { return "[EOS_E01] 'companyAClient.id' is empty."; } @Override public String getClientIdNotExistErrorMsg() { return "[EOS_E02] 'companyAClient.id' not match with DB records."; } @Override public String getClientNameNotFoundErrorMsg() { return "[EOS_E03] 'companyAClient.name' not match with DB records."; } } // 接口B的消息提供者实现 class InterfaceBMessageProvider implements ValidationMessageProvider { @Override public String getClientIdParseErrorMsg() { return "[E_XML_001] Parse Client ID error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/ID'."; } @Override public String getClientIdNotExistErrorMsg() { return "[E_XML_002] Client ID not found error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/ID'"; } @Override public String getClientNameNotFoundErrorMsg() { return "[E_XML_003] Client name not found error. Please check '/MSG/MSG.BODY/COMPANY/CLIENT/NAME'"; } }
然后公共校验方法接收这个提供者:
private void validateCommonFields(String clientId, String clientName, ValidationMessageProvider msgProvider) { validateClientId(clientId, msgProvider.getClientIdParseErrorMsg(), msgProvider.getClientIdNotExistErrorMsg()); validateClientName(clientName, msgProvider.getClientNameNotFoundErrorMsg()); // 其他公共字段校验... }
接口校验方法调用时传入对应的提供者:
private void checkInterfaceA(String clientId, String clientName, ...) { validateCommonFields(clientId, clientName, new InterfaceAMessageProvider()); // 接口A专属校验 } private void checkInterfaceB(String clientId, String clientName, ...) { validateCommonFields(clientId, clientName, new InterfaceBMessageProvider()); // 接口B专属校验 }
额外优化建议
- 把错误码和消息文案抽成常量类(比如
InterfaceAErrorCodes、InterfaceBErrorCodes),避免硬编码字符串,方便后续修改维护。 - 如果使用Spring等框架,可以把
ValidationMessageProvider的实现类注册为Bean,通过依赖注入使用,更符合框架设计思想。
内容的提问来源于stack exchange,提问作者TonyF93
相关产品推荐
相关产品推荐

