I am handling REST exceptions using @ControllerAdvice
and ResponseEntityExceptionHandler
in a spring Rest webservice. So far everything was working fine until I decided to add the URI
path(for which exception has occurred) into the BAD_REQUEST response.
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
logger.info(request.toString());
return handleExceptionInternal(ex, errorMessage(HttpStatus.BAD_REQUEST, ex, request), headers, HttpStatus.BAD_REQUEST, request);
}
private ApiError errorMessage(HttpStatus httpStatus, Exception ex, WebRequest request) {
final String message = ex.getMessage() == null ? ex.getClass().getName() : ex.getMessage();
final String developerMessage = ex.getCause() == null ? ex.toString() : ex.getCause().getMessage();
return new ApiError(httpStatus.value(), message, developerMessage, System.currentTimeMillis(), request.getDescription(false));
}
ApiError is just a Pojo class:
public class ApiError {
private Long timeStamp;
private int status;
private String message;
private String developerMessage;
private String path;
}
But WebRequest has not given any api to get the path for which the request failed. I tried:
request.toString()
returns -> ServletWebRequest: uri=/signup;client=0:0:0:0:0:0:0:1request.getDescription(false)
returns -> uri=/signupgetDescription
is pretty close to the requirement, but doesn't meet it. Is there any way to get only the uri part?
Casting WebRequest to ServletWebRequest solved the purpose. Instead of getRequestURL() , getRequestURI() be used to get the URI in the question.
public interface WebRequest extends RequestAttributes. Generic interface for a web request. Mainly intended for generic web request interceptors, giving them access to general request metadata, not for actual handling of the request.
The Method request. getRequestURI() returns URI with context path. For example, if the base URL of an application is http://localhost:8080/myapp/ (i.e. the context path is myapp), and I call request. getRequestURI() for http://localhost:8080/myapp/secure/users , it will return /myapp/secure/users .
Found the solution. Casting WebRequest
to ServletWebRequest
solved the purpose.
((ServletWebRequest)request).getRequest().getRequestURI().toString()
returns the complete path - http://localhost:8080/signup
There are multiple solutions to this problem.
1) One can get request URI and client information from WebRequest using webRequest.getDescription(true).
true will show user's information such as client id and false will just print URI.
2) Instead of WebRequest of Use HttpServletRequest directly in method definition as
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex,
HttpHeaders headers, HttpStatus status, WebRequest request, HttpServletRequest httpRequest) {
logger.info(httpRequest.getRequestURI());
return handleExceptionInternal(ex, errorMessage(HttpStatus.BAD_REQUEST, ex, request), headers, HttpStatus.BAD_REQUEST, request);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With