我正在使用 Spring MVC 将一些 servlet 迁移到 Spring 框架。目前,我们在每个 servlet 中对用户进行身份验证,如果身份验证失败,我们将执行以下操作:
if (authfailed)
{
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"You are not authorized.");
return;
}
前端是一个基于 YUI 的应用程序,当返回错误状态时,“失败”回调会显示一个对话框,其中包含上面给出的错误消息。
我知道在我的 Controller 中我可以获取响应对象并调用 sendError
,但这是处理此问题的最佳方法吗? sendError
还会抛出 IOException,因此我必须捕获它 - 在每个 Controller 的每个方法中插入一些烦人的代码。
我在处理异常时也遇到同样的问题 - Servlet 具有在 catch 方法中调用 sendError
的 try-catch block 。我知道我可以用
@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND)
但是异常处理类不需要在每个 Controller 类中吗?
最后,如果异常发生在从 Controller 调用的服务中,异常是否会向上冒泡到 Controller ,或者我应该在服务中处理异常(从而将这些异常处理问题插入服务层)?
这似乎比应有的更困难,但与 Spring 中的许多事情一样,我可能不明白发生了什么。我想做的就是在响应中发送错误状态和消息!
谢谢
保罗
最佳答案
看来您的问题本身已经有了大部分答案:)
重申一下,
有这样的 Controller
@RequestMapping("/test")
public String verifyAuth(HttpServletRequest request) throws NotFoundException {
String id = request.getParameter("id");
if (id == null)
throw new NotFoundException("Id not found in the request");
return "success";
}
在NotFoundException.java中声明异常类,
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Id Not Found")
public class NotFoundException extends Exception {
public NotFoundException(String msg) {
super(msg);
}
}
这个异常类不需要是每个 Controller 类。将其声明为公共(public)类并将其导入到每个所需的 Controller 中。
这是一种方法。如果您喜欢非 spring 风格,请在每个 Controller 参数中声明 HttpServletResponse 并执行
@RequestMapping("/test")
public String verifyAuth(HttpServletRequest request, HttpServletResponse response) {
...
try {
response.sendError(..)
catch(..) {}
}
或者您可以使用 View 来显示错误消息,
@RequestMapping("/test")
public String verifyAuth(HttpServletRequest request, Map<String, Object> map){
String id = request.getParameter("id");
if (id == null) {
map.put("status", HttpStatus.NOTFOUND);
map.put("reason", "Id Not Found");
return "error"
}
return "success";
}
确保您的 viewResolver 配置正确,并且在 error.jsp 中获取错误字符串,您可以说。
<body>
${status} ${reason}
</body>
使用漂亮的 css 定义 error.jsp,以应对您期望的所有类型的错误。 这些不是唯一的方法。有了 Spring ,你就可以自由地做任何事情。我见过很少有人渲染 json 对象来获取错误消息。
要回答您的另一个问题,即错误是否发生在 Controller 调用的服务中,取决于您的场景。例如,您正在尝试读取用户存储,如果发生用户存储不可用错误,我将自行处理从另一个副本用户存储(如果可用)读取,如果我发现用户不存在,我会将异常留给 Controller 进行 throw 。
关于spring-mvc - 从 Spring Controller 或服务返回错误和消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5757888/