Trigger 404 in Spring-MVC controller?

后端 未结 14 1181
攒了一身酷
攒了一身酷 2020-11-29 14:59

How do I get a Spring 3.0 controller to trigger a 404?

I have a controller with @RequestMapping(value = \"/**\", method = RequestMethod.GET) and for som

相关标签:
14条回答
  • 2020-11-29 15:44

    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.OK if found and to 404 if empty.

    @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); 
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 15:47

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

     @RequestMapping(value = "/**", method = RequestMethod.GET)
     public ModelAndView show() throws NoSuchRequestHandlingMethodException {
        if(something == null)
             throw new NoSuchRequestHandlingMethodException("show", YourClass.class);
    
        ...
    
      }
    
    0 讨论(0)
  • 2020-11-29 15:47

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

    @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)

    0 讨论(0)
  • 2020-11-29 15:50

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

    @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(); 
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 15:50

    I'd recommend throwing HttpClientErrorException, like this

    @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.

    0 讨论(0)
  • 2020-11-29 15:51

    Because it's always good to have at least ten ways of doing the same thing:

    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class Something {
        @RequestMapping("/path")
        public ModelAndView somethingPath() {
            return new ModelAndView("/", HttpStatus.NOT_FOUND);
        }
    }
    
    0 讨论(0)
提交回复
热议问题