处理PageNotFound的最佳实践,用于未映射的请求映射

时间:2014-01-26 13:35:11

标签: spring-mvc servlets

我的用例:
我的应用程序中有多个“逻辑部分”,由url分隔。类似的东西:
- someUrl / servletPath / onePartOfMyApplication / ...
- someUrl / servletPath / otherPartOfMyApplication / ...

现在我想以不同的方式处理每个部分的未映射请求(404s)。

我现在如何处理它:
我的web.xml:

...
<error-page>
 <error-code>404</error-code>
 <location>/servletPath/404.html</location>
</error-page>

我的控制员:

@Controller
public class ExceptionController
{
  @ResponseStatus(value = HttpStatus.NOT_FOUND)
  @RequestMapping(value = "/404.html")
  protected String show404Page(final HttpServletRequest request)
  {
    final String forward = (String) request.getAttribute("javax.servlet.forward.request_uri");

    // parse string and redirect to whereever, depending on context
    final String redirectPath = parse(forward);

    return "redirect: " + redirectPath;
  }
  ...

我的目标:
是否有更优雅(类似于弹簧)的处理404s,而不是在控制器或拦截器中解析请求并在我的web.xml中声明错误页面?

如果我的控制器应该看起来像这样会很好:

    @Controller
    public class ExceptionController
    {
      @ResponseStatus(value = HttpStatus.NOT_FOUND)
      @RequestMapping(value = "/onePartOfMyApplication/404.html")
      protected String show404PageForOnePart(final HttpServletRequest request)
      {
        // do something
        ...
        return "onePartPage";
      }

      @ResponseStatus(value = HttpStatus.NOT_FOUND)
      @RequestMapping(value = "/otherPartOfMyApplication/404.html")
      protected String show404PageForOtherPart(final HttpServletRequest request)
      {
        // do something different
        ...
        return "otherPartPage";
      }

1 个答案:

答案 0 :(得分:2)

我使用@ExceptionHandler注释。在控制器中我有类似的东西:

  private class ItemNotFoundException extends RuntimeException {
     private static final long serialVersionUID = 1L;
     public ItemNotFoundException(String message) {
        super(message);
     }
  }

  @ExceptionHandler
  @ResponseStatus(HttpStatus.NOT_FOUND)
  public void handleINFException(ItemNotFoundException ex) {

  }

private class ItemNotFoundException extends RuntimeException { private static final long serialVersionUID = 1L; public ItemNotFoundException(String message) { super(message); } } @ExceptionHandler @ResponseStatus(HttpStatus.NOT_FOUND) public void handleINFException(ItemNotFoundException ex) { }

然后我在Controller(或服务层)中抛出异常:

  @RequestMapping("/{id}")
  @ResponseBody
  public Item detail(@PathVariable int id) {
     Item item = itemService.findOne(id);
     if (item == null) { throw new ItemNotFoundException("Item not found!"); }
     return item;
  }

您可以在使用@ExceptionHandler注释的方法中执行任何您喜欢的操作。现在,在我的示例中,它显示了一个标准的404错误,您可以在web.xml中自定义,但您可以做更多,更多。请参阅文档:http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html