Way*_*neC 12 java spring spring-mvc content-negotiation
要全局处理可能在Controller外部发生的错误(例如HTTP 404),我的web.xml中的条目类似于以下内容:
<error-page>
<error-code>404</error-code>
<location>/errors/404</location>
</error-page>
Run Code Online (Sandbox Code Playgroud)
在我的ErrorController中,我有类似于以下的相应方法:
@Controller
@RequestMapping("/errors")
public class ErrorController {
@RequestMapping(value = "/404", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<ErrorResponse> error404() {
ErrorResponse errorBody = new ErrorResponse(404, "Resource Not Found!");
return new ResponseEntity<ErrorResponse>(errorBody, HttpStatus.NOT_FOUND);
}
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是ContentNegotiationManager
我配置的和消息转换器在这种情况下没有被使用.我怀疑由于请求被重定向到错误页面,因此内容协商中使用的原始请求属性将丢失,并将其视为完全独立的请求.(即原始请求/mycontroller/badresource.json - >/errors/404(没有文件扩展名))
在这样的错误处理程序中是否有任何方法确定和/或使用原始请求中请求的相应内容类型进行响应?
我为此想出了一些技巧,但它似乎有效。它基本上涉及错误处理中的额外转发以确定原始请求的文件扩展名。
在我的 web.xml 中,我将错误转发到中间操作:
<error-page>
<error-code>404</error-code>
<location>/errors/redirect</location>
</error-page>
Run Code Online (Sandbox Code Playgroud)
然后,在转发到将生成错误响应的操作之前,将检查原始请求是否有文件扩展名。如果有,它会确保将其附加到转发 URI。HTTP 标头会自动转发,因此如果您设置的内容协商仅涉及文件扩展名或 HTTP 标头,这将有效地允许“错误页面”以适当的内容类型返回错误。
@Controller
@RequestMapping("/errors")
public class ErrorController {
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public void errorRedirect(HttpServletRequest request, HttpServletResponse response) {
// Get original request URI
String uri = (String)request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE);
// Try to determine file extension
String filename = WebUtils.extractFullFilenameFromUrlPath(uri);
String extension = StringUtils.getFilenameExtension(filename);
extension = StringUtils.hasText(extension) ? "." + extension : "";
// Forward request to appropriate handler with original request's file extension (i.e. /errors/404.json)
String forwardUri = "/errors/404" + extension);
request.getRequestDispatcher(forwardUri).forward(request, response);
}
@RequestMapping(value = "/404", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<ErrorResponse> error404() {
ErrorResponse errorBody = new ErrorResponse(404, "Resource Not Found!");
return new ResponseEntity<ErrorResponse>(errorBody, HttpStatus.NOT_FOUND);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2887 次 |
最近记录: |