代码之家  ›  专栏  ›  技术社区  ›  NA.

触发弹簧MVC控制器404?

  •  168
  • NA.  · 技术社区  · 15 年前

    我如何得到 Spring 3.0控制器触发404?

    我有一个控制器 @RequestMapping(value = "/**", method = RequestMethod.GET) 还有一些 URLs 访问控制器时,我希望容器生成404。

    12 回复  |  直到 6 年前
        1
  •  296
  •   matt b    14 年前

    从Spring3.0开始,您还可以抛出用 @ResponseStatus 注释:

    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public class ResourceNotFoundException extends RuntimeException {
        ...
    }
    
    @Controller
    public class SomeController {
        @RequestMapping.....
        public void handleCall() {
            if (isFound()) {
                // whatever
            }
            else {
                throw new ResourceNotFoundException(); 
            }
        }
    }
    
        2
  •  35
  •   matt b    15 年前

    重写方法签名以便它接受 HttpServletResponse 作为参数,以便可以调用 setStatus(int) 关于它。

    http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping-arguments

        3
  •  24
  •   michal.kreuzman    12 年前

    我想说的是,Spring提供的404默认情况下有例外(不仅如此)。见 Spring documentation 详情。因此,如果您不需要自己的异常,您只需执行以下操作:

     @RequestMapping(value = "/**", method = RequestMethod.GET)
     public ModelAndView show() throws NoSuchRequestHandlingMethodException {
        if(something == null)
             throw new NoSuchRequestHandlingMethodException("show", YourClass.class);
    
        ...
    
      }
    
        4
  •  19
  •   Community c0D3l0g1c    7 年前

    从弹簧3.0.2开始,您可以返回 ResponseEntity<T> 由于控制器的方法:

    @RequestMapping.....
    public ResponseEntity<Object> handleCall() {
        if (isFound()) {
            // do what you want
            return new ResponseEntity<>(HttpStatus.OK);
        }
        else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
    

    (responseentity<t>比@responsebody注释更灵活-请参见 another question )

        5
  •  14
  •   user957654    10 年前

    你可以使用 @ControllerAdvice 为了处理你的例外情况, @controlleradvice注释类的默认行为将帮助所有已知的控制器。

    所以当任何控制器抛出404错误时,都会调用它。

    如下所示:

    @ControllerAdvice
    class GlobalControllerExceptionHandler {
        @ResponseStatus(HttpStatus.NOT_FOUND)  // 404
        @ExceptionHandler(Exception.class)
        public void handleNoTFound() {
            // Nothing to do
        }
    }
    

    并在web.xml中映射这个404响应错误,如下所示:

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

    希望有帮助。

        6
  •  9
  •   Ralph    11 年前

    如果您的控制器方法是用于文件处理之类的事情,那么 ResponseEntity 非常方便:

    @Controller
    public class SomeController {
        @RequestMapping.....
        public ResponseEntity handleCall() {
            if (isFound()) {
                return new ResponseEntity(...);
            }
            else {
                return new ResponseEntity(404);
            }
        }
    }
    
        7
  •  6
  •   Liviu Stirb    7 年前

    虽然标记的答案是正确的,但有一种方法可以毫无例外地实现这一点。服务回来了 Optional<T> 搜索到的对象,并且此对象映射到 HttpStatus.OK 如果找到,则返回404。

    @Controller
    public class SomeController {
    
        @RequestMapping.....
        public ResponseEntity<Object> handleCall() {
            return  service.find(param).map(result -> new ResponseEntity<>(result, HttpStatus.OK))
                    .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
        }
    }
    
    @Service
    public class Service{
    
        public Optional<Object> find(String param){
            if(!found()){
                return Optional.empty();
            }
            ...
            return Optional.of(data); 
        }
    
    }
    
        8
  •  5
  •   mmatczuk    9 年前

    我建议你扔 httpClientErrorException(httpClientErrorException) ,像这样

    @RequestMapping(value = "/sample/")
    public void sample() {
        if (somethingIsWrong()) {
            throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
        }
    }
    

    您必须记住,这只能在将任何内容写入servlet输出流之前完成。

        9
  •  2
  •   pilot    6 年前

    这有点晚了,但是如果你用 Spring Data REST 那么已经有了 org.springframework.data.rest.webmvc.ResourceNotFoundException 它也使用 @ResponseStatus 注释。不再需要创建自定义运行时异常。

        10
  •  1
  •   AbdusSalam    7 年前

    另外,如果你想从你的控制器返回404状态,你所需要的就是这样做。

    @RequestMapping(value = "/somthing", method = RequestMethod.POST)
    @ResponseBody
    public HttpStatus doSomthing(@RequestBody String employeeId) {
        try{
      return HttpStatus.OK;
        } 
        catch(Exception ex){ 
      return HttpStatus.NOT_FOUND;
        }
    }
    

    通过这样做,您将收到404错误,以防您想从控制器返回404。

        11
  •  0
  •   Rajith Delantha    12 年前

    只需使用web.xml添加错误代码和404错误页。但要确保404错误页不能位于WEB-INF下。

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

    这是最简单的方法,但有一些限制。假设您想为这个页面添加与其他页面相同的样式。你不能这样做。你必须使用 @ResponseStatus(value = HttpStatus.NOT_FOUND)

        12
  •  0
  •   Atish Narlawar    10 年前

    使用设置配置web.xml

    <error-page>
        <error-code>500</error-code>
        <location>/error/500</location>
    </error-page>
    
    <error-page>
        <error-code>404</error-code>
        <location>/error/404</location>
    </error-page>
    

    创建新控制器

       /**
         * Error Controller. handles the calls for 404, 500 and 401 HTTP Status codes.
         */
        @Controller
        @RequestMapping(value = ErrorController.ERROR_URL, produces = MediaType.APPLICATION_XHTML_XML_VALUE)
        public class ErrorController {
    
    
            /**
             * The constant ERROR_URL.
             */
            public static final String ERROR_URL = "/error";
    
    
            /**
             * The constant TILE_ERROR.
             */
            public static final String TILE_ERROR = "error.page";
    
    
            /**
             * Page Not Found.
             *
             * @return Home Page
             */
            @RequestMapping(value = "/404", produces = MediaType.APPLICATION_XHTML_XML_VALUE)
            public ModelAndView notFound() {
    
                ModelAndView model = new ModelAndView(TILE_ERROR);
                model.addObject("message", "The page you requested could not be found. This location may not be current.");
    
                return model;
            }
    
            /**
             * Error page.
             *
             * @return the model and view
             */
            @RequestMapping(value = "/500", produces = MediaType.APPLICATION_XHTML_XML_VALUE)
            public ModelAndView errorPage() {
                ModelAndView model = new ModelAndView(TILE_ERROR);
                model.addObject("message", "The page you requested could not be found. This location may not be current, due to the recent site redesign.");
    
                return model;
            }
    }