I'm new to spring, so please excuse my ignorance. I'm trying to "return" a custom response when a given method parameter, which is "required", is null. the current response, from spring, is:
{
"timestamp": 1477060294961,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MissingServletRequestParameterException",
"message": "Required String parameter 'bookname' is not present",
"path": "/getbook"
}
I am trying to get to a point where it "returns":
{
"status": 400,
"error": {
// custom error body
}
}
I thought a nice way of doing this would be to have a custom "parameter annotation". This would also make the code much more readable and store useful information about this endpoint parameter.
I followed the example given here, but I'm not sure where or how to return the custom response?
So far I have the annotation:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface customParameter {
String value() default "";
boolean required() default false;
String defaultValue() default ValueConstants.DEFAULT_NONE;
String customInfo() default "blar blar";
}
the "endpoint" :
@RequestMapping(value = "/getbook", method = {RequestMethod.POST})
public ResponseEntity<BookResponse> getBookInfo(
@customParameter(value = "bookname", required = true, customInfo = "extremely valuable book")
final String bookname
) {
return new bookRequest(bookname).getResponse;
}
and have an custom resolver :
public class CustomAnnotationResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(customParameter.class) != null;
}
@Override
public Object resolveArgument(MethodParameter methodparameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CustomParameter customParameter = methodparameter.getParameterAnnotation(CustomParameter.class);
String parameter = webRequest.getParameter(CustomParameter.value());
// todo: do Validation here
if (customParameter == null) {
if (Parameter.required()) {
String customInfo = customParameter.customInfo();
String body getBody(customInfo);
new ResponseEntity(body, 400); // so the problem is here!! how do I return this response??
}
}
return webRequest.getParameter(customParameter.value());
}
}
I have also "registered" this resolver with the webConfig :
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new CustomAnnotationResolver());
}
}
any help with this implementation or any other suggestions of how to do this would be fantastic. Thanks all :)
Thank you @growlingchaos, brilliant, this is the solution.
@ControllerAdvice
@RestController
public class customExceptionAdvice {
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity handleConflict(BadRequestException e, HttpServletResponse response)
throws IOException {
return new ResponseEntity(e.getErrorBody(), HttpStatus.BAD_REQUEST);
}