Spring
Spring

Reputation: 11855

Spring MVC custom message for HTTP 400

I have several SprigMVC methods like this below, returning either a ModelAndView or a Responsebody. When users makes a request to these urls missing the required parameters they naturally get the message "Required String parameter 'id' is not present".

From security perspective I want to hide this detailed description messages from users. So a hacker don't easily know the missing parameters and will get a 400 error without any description. Is this possible via a spring configuration/Spring Security or I have to manually refactor all my methods to return a custom message somehow.

@RequestMapping(value = "/payment", method = RequestMethod.GET)
public ModelAndView getReponse(@RequestParam(value = "id", required = true)) {

    return model;
}

@RequestMapping(value = "/status", method = RequestMethod.GET)
public @ResponseBody String getStatus(@RequestParam(value = "id", required = true) String id) {

    return "string";
}

Upvotes: 5

Views: 4316

Answers (2)

Michal M
Michal M

Reputation: 1568

I personally upvoted Daniel Olszewski's answer because it's hip, nice, concise and readable, although in a customer-facing, publicly available site (when you go beyond the fast prototyping with Spring Boot phase and need to be perfectly sure that nothing gets through) one may want to use it together with the plain-old error-page in web.xml approach (some examples here: Handle error 404 with Spring controller).

It may not be fun (I, personally, despise anything XML related beyond explainability), but (unless you're not using web.xml at all in favor of WebApplicationInitializer), web.xml is almost the lowest layer in a web app and no error page (no matter the exception or URL mapping) will get through it, just remember to map all the HTTP status codes (i.e. have one default error-page element without the child error-code element).

The solution for WebApplicationInitializer is analogous, some xamples here: Using Spring MVC 3.1+ WebApplicationInitializer to programmatically configure session-config and error-page.

The lowest layer approach would be to set the error page contener-wide, e.g. for Tomcat: http://linux-sxs.org/internet_serving/c581.html.

Upvotes: 4

Daniel Olszewski
Daniel Olszewski

Reputation: 14401

What you actually need is a global handler for MissingServletRequestParameterException, which is thrown by Spring when a request parameter is missing. The easiest way to tackle this problem is to use ControllerAdvice that will handle it for all your controllers.

import org.springframework.web.bind.MissingServletRequestParameterException;

@ControllerAdvice
class MissingServletRequestParameterExceptionHandler {
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleMissingParameter() {
        return "Your custom result";
    }
}

If you want to hide the missing parameter message only for a particular controller, just move handleMissingParameter method to this controller without creating the ControllerAdvice.

Upvotes: 9

Related Questions