处理401错误(Spring Security)
我可以处理404错误。
@ResponseStatus(value = HttpStatus.NOT_FOUND) @ExceptionHandler(NoHandlerFoundException.class) @ResponseBody public void noHandlerFoundException (HttpServletResponse response) throws IOException{ //some code }
但是如何处理401错误?
编辑我使用的是Java而不是web.xml
编辑我应该在NoHandlerFoundException中放置什么来处理HttpStatus.UNAUTHORIZED
编辑
validation失败时,我的方法不成功validation:
public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter { protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { SecurityContextHolder.clearContext(); if (logger.isDebugEnabled()) { logger.debug("Authentication request failed: " + failed.toString()); logger.debug("Updated SecurityContextHolder to contain null Authentication"); logger.debug("Delegating to authentication failure handler " + failureHandler); } // response.setCharacterEncoding("UTF-8"); // response.getWriter().write(jsonService.toString(jsonService.getResponse(false, "Не удалось авторизоваться", "401"))); rememberMeServices.loginFail(request, response); failureHandler.onAuthenticationFailure(request, response, failed); } }
此代码发送401错误html。 我需要发送json,你可以在评论中看到它。
这是一个完整的处理程序,适用于所有一小部分错误页面:
@Controller public class ErrorCodeController extends BaseController { @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage400", method=RequestMethod.GET) @ResponseStatus(value = HttpStatus.BAD_REQUEST) public String handleBadRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.BAD_REQUEST); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage401", method=RequestMethod.GET) @ResponseStatus(value=HttpStatus.UNAUTHORIZED,reason="Unauthorized Request") public String handleUnauthorizedRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.UNAUTHORIZED); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage404", method=RequestMethod.GET) @ResponseStatus(HttpStatus.NOT_FOUND) public String handleNotFoundRequest(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.NOT_FOUND); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) @RequestMapping(value="errorPage500", method=RequestMethod.GET) @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR,reason="Internal Server Error") public String handleInternalServerError(ApplicationException ex,HttpServletResponse response, ModelMap map) { map.addAttribute("http-error-code", HttpStatus.INTERNAL_SERVER_ERROR); return processErrorCodes(ex,response,map); } @ExceptionHandler(ApplicationException.class) public void handleApplicationExceptions(Throwable exception, HttpServletResponse response) { } private String processErrorCodes(ApplicationException ex,HttpServletResponse response, ModelMap map){ map.addAttribute("class", ClassUtils.getShortName(ex.getClass())); map.addAttribute("message", ex.getMessage()); map.addAttribute("errorMessage", ex.getErrorMessage()); map.addAttribute("errorCode", ex.getErrorCode()); map.addAttribute("timestamp", ex.getCurrentDate()); return "errorPage"; } }
基础控制器:
@Controller @RequestMapping("/") public class BaseController { // Remember to add any exception that you suspect can be thrown in this web application. @ExceptionHandler({ApplicationException.class,NullPointerException.class}) public ModelAndView handleException(Throwable exception,HttpServletRequest req) { ModelMap model = new ModelMap(); ApplicationException ex = new ApplicationException(); String timeStamp = ex.getCurrentDate().toString(); //String temp = ClassUtils.getShortName(ex.getClass()); //model.addAttribute("class", ClassUtils.getShortName(ex.getClass())); model.addAttribute("timeStamp", timeStamp); return new ModelAndView("errorPage", model); }
Web.xml:
myApp 400 /errorPage400.xhtml 401 /errorPage401.xhtml 404 /errorPage404.xhtml 500 /errorPage500.xhtml java.lang.Throwable /errorPage.xhtml
我知道这是一个古老的话题,但我也是如此,所以这里的解决方案只适用于Tomcat。
在*DispatcherServletInitializer
/ WebAppInitializer
的#onStartup(...)
方法中调用以下方法。
Field appContextInFacade = ApplicationContextFacade.class.getDeclaredField("context"); appContextInFacade.setAccessible(true); ApplicationContext appContext = (ApplicationContext) appContextInFacade.get(servletContext); Field appContextInContext = ApplicationContext.class.getDeclaredField("context"); appContextInContext.setAccessible(true); StandardContext context = (StandardContext) appContextInContext.get(appContext); ErrorPage defaultErrorPage = new ErrorPage(); defaultErrorPage.setLocation("/myinternalerrorhandlercontroller"); context.addErrorPage(defaultErrorPage); // You may have to use reflection here as well.
然后添加一个能够处理这些错误请求的控制器:
@RequestMapping("/myinternalerrorhandlercontroller") public ResponseEntity renderErrorPage(HttpServletRequest httpRequest)
您可以使用以下方法提取错误详细信
(Integer) httpRequest.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
重要的提醒:
- 您必须处理所有
RequestMethod
。 - 您必须处理所有
Content-Type
s(=>返回字节或注册一个回退HttpMessageConverter,它可以将您的错误对象转换为json,无论请求的是什么)。 - 您的错误页面绝不能抛出exception或无法返回响应。
- 仅当未调用常用的
@ExceptionHandler
或类似机制或(无法执行)时,才会显示错误页面。 - 不要访问应用程序状态,例如用户身份validation,因为您不在其范围内,并且可能无法使用或包含无效数据。
你可以查一下
HttpStatus.UNAUTHORIZE
请参阅: 有关HttpStatus的信息(Spring Framework)