Java 在 Spring-MVC 控制器中触发 404?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2066946/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:11:14  来源:igfitidea点击:

Trigger 404 in Spring-MVC controller?

javaspringspring-mvc

提问by NA.

How do I get a Spring3.0 controller to trigger a 404?

如何让Spring3.0 控制器触发 404?

I have a controller with @RequestMapping(value = "/**", method = RequestMethod.GET)and for some URLsaccessing the controller, I want the container to come up with a 404.

我有一个控制器@RequestMapping(value = "/**", method = RequestMethod.GET)和一些网址访问控制,我想容器拿出404。

采纳答案by axtavt

Since Spring 3.0 you also can throw an Exception declared with @ResponseStatusannotation:

从 Spring 3.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(); 
        }
    }
}

回答by matt b

Rewrite your method signature so that it accepts HttpServletResponseas a parameter, so that you can call setStatus(int)on it.

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

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

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

回答by michal.kreuzman

I would like to mention that there's exception (not only) for 404 by default provided by Spring. See Spring documentationfor details. So if you do not need your own exception you can simply do this:

我想提一下,默认情况下,Spring 提供了 404 的例外(不仅)。有关详细信息,请参阅Spring 文档。因此,如果您不需要自己的异常,您可以简单地执行以下操作:

 @RequestMapping(value = "/**", method = RequestMethod.GET)
 public ModelAndView show() throws NoSuchRequestHandlingMethodException {
    if(something == null)
         throw new NoSuchRequestHandlingMethodException("show", YourClass.class);

    ...

  }

回答by Rajith Delantha

Simply you can use web.xml to add error code and 404 error page. But make sure 404 error page must not locate under WEB-INF.

只需使用 web.xml 添加错误代码和 404 错误页面即可。但请确保 404 错误页面不得位于 WEB-INF 下。

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

This is the simplest way to do it but this have some limitation. Suppose if you want to add the same style for this page that you added other pages. In this way you can't to that. You have to use the @ResponseStatus(value = HttpStatus.NOT_FOUND)

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

回答by Ralph

If your controller method is for something like file handling then ResponseEntityis very handy:

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

@Controller
public class SomeController {
    @RequestMapping.....
    public ResponseEntity handleCall() {
        if (isFound()) {
            return new ResponseEntity(...);
        }
        else {
            return new ResponseEntity(404);
        }
    }
}

回答by Atish Narlawar

Configure web.xml with setting

使用设置配置 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>

Create new controller

创建新控制器

   /**
     * 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;
        }
}

回答by Atish Narlawar

you can use the @ControllerAdviceto handle your Exceptions , The default behavior the @ControllerAdvice annotated class will assist all known Controllers.

您可以使用@ControllerAdvice来处理您的异常,@ControllerAdvice 注释类的默认行为将协助所有已知的控制器。

so it will be called when any Controller you have throws 404 error .

因此,当您拥有的任何控制器抛出 404 错误时,它将被调用。

like the following :

像下面这样:

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

and map this 404 response error in your web.xml , like the following :

并在您的 web.xml 中映射此 404 响应错误,如下所示:

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

Hope that Helps .

希望有帮助。

回答by Lu55

Since Spring 3.0.2 you can return ">ResponseEntity<T>as a result of the controller's method:

从 Spring 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> is a more flexible than @ResponseBody annotation - see another question)

(ResponseEntity<T> 比 @ResponseBody 注释更灵活 - 请参阅另一个问题

回答by mmatczuk

I'd recommend throwing HttpClientErrorException, like this

我建议像这样抛出HttpClientErrorException

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

You must remember that this can be done only before anything is written to servlet output stream.

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

回答by user1121883

While the marked answer is correct there is a way of achieving this without exceptions. The service is returning Optional<T>of the searched object and this is mapped to HttpStatus.OKif found and to 404 if empty.

虽然标记的答案是正确的,但有一种方法可以毫无例外地实现这一目标。该服务正在返回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); 
    }

}