我在DAO方法中有以下代码:
public void someMethod() throws CustomException {
try {
... do something ...
}catch(Exception e) {
if(e.getCause() instanceOf org.hibernate.ConstraintViolationException && e.getMessage().contains("child record found")) {
throw new CustomException("Child records found.");
}else {
throw new CustomException("Unable to update.");
}
}
}
在服务层:
public void someMethod() throws CustomException {
dao.someMethod();
}
在控制器中:
public ResponseObject someMethod() {
ResponseObject response = new ResponseObject();
try {
service.someMethod();
response.setMessage("success");
}catch(CustomException e) {
response.setMessage(e.getMessage());
}
return response;
}
我是否按照最佳做法正确行事? 我还能做些什么来使它成为正确的?
任何帮助表示赞赏!
答案 0 :(得分:0)
我注意到的一些事情。首先,仅在特殊情况下使用例外。换句话说,例外应该是例外,而不是常态。从它的外观来看,“ConstraintViolationException”是预期很多的东西。 异常会使代码更加难以调试,并且可以减少JVM优化,从而大大加快程序执行速度。
其次,如果调用者可以合理地预期恢复,则应该只使用已检查的异常(不从RuntimeException扩展的异常)。在您的情况下,除了给客户端一个错误消息之外,调用者不会做任何事情来恢复。 通过抛出已检查的异常,可以强制调用者在catch子句中处理异常或将其向外传播。 (两者都是这些陷阱,详见Joshua Bloch的优秀着作“Effective Java”。)
第三,在异常处理中,您尝试解析错误消息。这可能是非常有问题的,因为第三方经常更改其错误消息,因为它们 不属于API的一部分。一旦发生这种情况,您的代码就会被破坏。异常处理中的另一个小问题是将JPA实现与hibernate联系起来。如果以后要更改为EclipseLink会怎么样?
有办法解决所有这些问题 摆脱DAO中的异常处理。 将以下方法添加到DAO:
boolean childRecordExists(Record record)
然后,在你的控制器中,有类似的东西:
if (service.childRecordExists()){
response.setMessage("Failed. A child record exists"); //a useful error message for the user, as you know *exactly* why failure happened
} else {
service.someMethod();
response.setMessage("Success");
}
您需要在控制器中使用某种exceptionHandler。 (如果您使用的是Spring MVC,则可以使用ExceptionHandler注释将其添加为另一种方法。) 这将解决真正例外的事情(日常用户体验不同寻常的事情,以及用户无法修复的事情。)