The parameters required by this Resource are:
1) from: a valid email address to send mails.
2) subject: the subject of mail.
3) to: a valid email address the mail send to.
4) text: the content of mail.
Because our project is using Spring to do everything we need and it can do. So Spring Rest Controller is my best option to implement this Resource.
the declaration of my resource is:
@RequestMapping ( method = { RequestMethod.POST, RequestMethod.GET } )
@ResponseStatus ( HttpStatus.OK )
public void sendEmail( @RequestParam ( value = "from" ) String from,
@RequestParam ( value = "subject" ) String subject,
@RequestParam ( value = "to" ) String to,
@RequestParam ( value = "text" ) String text,
final HttpServletResponse response ) throws Exception
And I test it by using following url.
url/subject=hello&to=sean@abc.com&text=this+is+hello+from+Sean
Because the parameter from is missing and the system should return a 400 exception with the right error message:
HTTP Status 400 - Required String parameter 'from' is not present
type Status report
message Required String parameter 'from' is not present
description The request sent by the client was syntactically incorrect (Required String parameter 'from' is not present).
Apache Tomcat/7.0.23
however, what I get is:
HTTP Status 400 -
type Status report
description The request sent by the client was syntactically incorrect ().
So what I need is how to customise the error message.
Actually, Spring does provide an exception for this case, it called
MissingServletRequestParameterException and returned the correct error message that what exact we want. But for some reason, the client side did not get the correct error message, but only the right status code which is 400.
My Solution (Also the solution shared by people online already):
Create my own AnnotationMethodHandlerAdapter and override the method invokeHandlerMethod.
public class AnnotationMethodExceptionHandlerAdapter extends
AnnotationMethodHandlerAdapter
{
@Override
protected ModelAndView invokeHandlerMethod( HttpServletRequest request,
HttpServletResponse response, Object handler ) throws Exception
{
try
{
return super.invokeHandlerMethod( request, response, handler );
}
catch ( MissingServletRequestParameterException e )
{
request.setAttribute( "EXCEPTION_NAME", e.getClass().getName() );
response.sendError( HttpServletResponse.SC_BAD_REQUEST, e.getMessage() );
return null;
}
catch ( Exception e )
{
request.setAttribute( "EXCEPTION_NAME", e.getClass().getName() );
response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage() );
return null;
}
}
}
I am not sure is there any exception which is not a MissingServletRequestParameterException can be thrown by super.invokeHandlerMethod( request, response, handler ); and I do know what status should return in that case. So at here I just return 500.
And modify my servlet config.
<!--To enable @RequestMapping process on type (class) level -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!--To enable @RequestMapping process on method level -->
<bean class="YourProjectPath.AnnotationMethodExceptionHandlerAdapter"/>
Do not need use
<mvc:annotation-driven/>
Then you will get the correct error message.
As I mentioned before and you can seen below, Spring does return the correct error message, but I do not know why client can not get it.
Hope this is helpful to you if you are struggling with the same problem with I got.