Error message in URL using Spring REST
-
21-12-2019 - |
Frage
I am developing a project using Spring REST web services, where I need to show graceful error messages when an exception/error occurs. I followed this tutorial (http://www.javacodegeeks.com/2013/02/exception-handling-for-rest-with-spring-3-2.html) for exception handling using SpringREST. I get the proper output when there is no exception/error i.e. in form of an XML. The issue arises when an exception occurs. Here is part of the code base where an exception occurs if I do not pass the testId in
localhost:8080/test?testId=
The class outputs a response in form of a XML, so when an exception occurs, instead of showing the error message as figure 1 below, it shows error message as figure 2. If I do "View Page Source", I get the correct exception message (as figure 1). But I need the exception message directly. Could anyone, please suggest a solution?
@RequestMapping(value = "/test",
method = RequestMethod.GET,
produces = "application/xml")
public @ResponseBody String testResource(
@RequestParam(value="testId", required=true) String testId)
throws CustomRestException{
if (testId == null || testId.equals(""))
{
LOG.error( "testResource(): " + TestUtilsException.NULL_TEST_ID_ERROR_MSG );
//The error message is: The test Id is required and cannot be null or empty
throw new CustomRestException(TestUtilsException.NULL_TEST_ID_ERROR_MSG);
}
}
Figure 1 Figure 2
Other helper classes:
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
public RestResponseEntityExceptionHandler() {
super();
}
@ExceptionHandler(value = { CustomRestException.class })
@ResponseBody
protected ResponseEntity<Object> handleNotFound(final RuntimeException ex, final WebRequest request) {
final String bodyOfResponse = ex.getMessage();
return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request);
}
}
public class CustomRestException extends RuntimeException {
public CustomRestException() {
super();
}
public CustomRestException(final String message, final Throwable cause) {
super(message, cause);
}
public CustomRestException(final String message) {
super(message);
}
public CustomRestException(final Throwable cause) {
super(cause);
}
}
Lösung
The @ControllerAdvice
approach should work, although I don't think there's any need for the base class - you can just use @ExceptionHandler
with Spring 4. But you are returning a response body that cannot be converted to Xml (it's a plain String), so you are getting an empty response and probably a 405 instead of a 500. If you want an Xml response you have to provide a body that can be converted (or else provide an HttpMessageConverter
that can do it).
Andere Tipps
Consider doing this.
public class BaseController{
@ExceptionHandler(value = { CustomRestException.class })
protected @ResponseBody ResponseEntity<ErrorResponse > handleNotFound(final RuntimeException ex, final WebRequest request) {
System.out.println("is executed in handler");
final String bodyOfResponse = ex.getMessage();
return new ResponseEntity<ErrorResponse >(new ErrorResponse (bodyOfResponse), null, HttpStatus.NOT_FOUND);
}
}
In your controller do this.
@Controller
public class HomeController extends BaseController {//Your code here}
And create this class.
@XmlRootElement
public class ErrorResponse {
public String error;
}
Finally add to your class the following code
if (testId == null || testId.equals(""))
{
throw new CustomRestException("DD");
}
That will create an XML response as follows.
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<successResponse> <error>DD</error> </successResponse>
This will handle all the exception an is not needed to add @ControllerAdvice, that seems need to add their own MessageConverters that is why the answer is not converted to XML, I read that here.
I added ,produces = "application/xml"
and remove it, and is still working as I think you want. Please let me know if this was useful.