11

I want to trigger 404 page whenever I wasn't passed all of the parameters. Lets say I have the following URI:

/myapp/op?param1=1&param2=2@param3=3

In case on of the parameters wasn;t invoked I want to return 404 page. I tried doing:

@ResponseStatus(HttpStatus.NOT_FOUND)
@RequestMapping(value = "op", params = { "!param1" })
public void missingArg() {
}

but then I get an exception telling me there is ambiguity between methods that handle missing second and third parameter.

How can I accomplish this, then?

3 Answers 3

27

If you're using Spring 3.1 you can define an exception class like so:

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public final class ResourceNotFoundException extends RuntimeException {
   //  class definition
}

Now whenever you throw that exception, Spring will return the http status defined in your @ResponseStatus annotation. For example:

@RequestMapping(value = "/op")
public void methodWithRequestParams(@RequestParam(value = "param1", required = false) String param1, 
        @RequestParam(value = "param2", required = false) String param2) {
  if (param1 == null || param2 == null) {
    throw new ResourceNotFoundException();
  }
}

will return a 404 whenever param1 or param2 is null.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that worked. Although this solution seems a bit awkward to me it got the job done.
How do you get a custom body/payload
6

You do not have to implement the missingArg() function. If there is no matching method for the incoming request, then Spring's HandlerExceptionResolver will handle it and return a response with an appropriate status code.

Spring will automatically convert the request parameters into method parameters if you use the @RequestParam annotation:

@RequestMapping(value = "/op")
public void methodWithRequestParams(@RequestParam("param1") String param1, 
        @RequestParam("param2") String param2, 
        @RequestParam("param3") String param3) {

    // do something with params
}

By convention, the methodWithRequestParams() method will not be called if not all params are part of the request (unless the required attribute of the @RequestParam is set to false).

Also note that the parameters does not have to be Strings.

2 Comments

The problem with this is that the repsonse code is 400 (or something other than 404) - I don't have control over what response code or what page is being returned.
Well, a 400 - Bad Request is in my opinion a more accurate response code that the 404. After all the resource (identified with by the /op url) exists, but the request parameters are wrong, i.e. a bad request. If you would like a specific resource and a 404 response if it does not exist, I suggest that you use @RequestMapping("/op/{id}") in conjunction with the @PathVariable annotation.
1

Echoing what matsev said in the comments of another answer, you should not be using @ResponseStatus(HttpStatus.NOT_FOUND) in this case, but rather @ResponseStatus(HttpStatus.BAD_REQUEST).

@ResponseStatus(HttpStatus.NOT_FOUND) should be used when the request was formed properly, but the resource isn't there.

Comments

Your Answer

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