0

Im am writing a Spring MVC @Controller. On a @RequestMapping method I would like to return a View name OR report back a 404 HTTP status code.

How can I continue using Spring View Resolver (for when I need a view) and control response error code without throwing an exception?

3
  • why not throw exception? You can process it by your code @ExceptionHandler(Exception.class) @ResponseBody @ResponseStatus(HttpStatus.NOT_FOUND) Commented Dec 19, 2013 at 17:32
  • Short answer: Because it is not an exceptional event. Long answer: It can be frequent (due to bad API usage), and it would be a situation where throwing an exception is not what I want. The answer right in the spot is simple (return a 404 return code), there is no need to handle an application error (the catch block performed by Spring). After all it is Spring, but it is much more Java, right?! ;) Commented Dec 19, 2013 at 18:18
  • 1
    ok thx it make sense, going to find my direct setting of responce, in 5 min Commented Dec 19, 2013 at 18:20

3 Answers 3

1

just raw draft

//initialised by init
private Map<String, View> viewsMap;

@RequestMapping(value = "/{path}")
@ResponseStatus(HttpStatus.OK)
public View getResponse(HttpServletResponse resp, @PathVariable String path)  {
    if (viewsMap.get(path ) != null){
        return viewsMap.get(path );
    }
    resp.setStatus(404);
    return null;
}
Sign up to request clarification or add additional context in comments.

3 Comments

That is quite a hack because of the "strange feeling" null return and the need for a Map. Why not return a 'String'? Is 'null' return only viable with 'View'?
yes it is hack :), sorry I do not have time to improve it now. String should be oK. Idea was to use map to decide if it is valid path or not.
Yes, with String it is also ok: response.setStatus(HttpServletResponse.SC_NOT_FOUND); return null; It does the thing. But somehow it is not yet what I want: return null is hurting me and the response body is blank (different from other 404 responses by Spring). Voting answer as useful.
1

You'd need to implement your own ViewResolver and a View that returns a particular HTTP status code. You can extend InternalResourceViewResolver (or whatever you're using now).

public class MyViewResolver extends InternalResourceViewResolver {
    public static final String HTTP_404_VIEW = "http404view";

    public View resolveViewName(String viewName, Locale locale) throws Exception {
        if (HTTP_404_VIEW.equals(viewName)) {
            return new StatusCodeView(404);
        } 
        else 
        {
            return super.resolveViewName(viewName, locale);
        }
    }
}

public class StatusCodeView implements View
{
     private final int code;

     public StatusCodeView(int code)
     {
          this.code = code;
     }

     public void render(Map model, HttpServletRequest request, HttpServletResponse response)
     {
          response.sendError(this.code);
     }
}

In your controller, just return MyViewResolver.HTTP_404_VIEW.

1 Comment

I was looking for a more streamlined solution. Is this the only way to deal with Spring MVC for my "not that special" case? (I'm also exploring, thank you!)
0

The best way I found to solve this is using directly the provided View Resolver for both cases. I simply created a view (in my case a .jsp file) for "not found" responses and:

response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return "error/" + HttpServletResponse.SC_NOT_FOUND;

Extra: as there can be different ways to trigger a HTTP error response, I also mapped the error pages in web.xml to have a similar view for same HTTP error code responses.

<error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/views/error/404.jsp</location>
</error-page>

A little work for what I needed, but it made me set HTTP error handling more accurately in my application.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.