How to include a message in a BadRequestException?
Solution 1
There is a really simple approach to this as shown below.
Response.ResponseBuilder resp_builder=Response.status(Response.Status.BAD_REQUEST);
resp_builder.entity(e.getMessage());//message you need as the body
throw new WebApplicationException(resp_builder.build());
if you need to add headers, response media type or some other functionality, ResponseBuilder provides them all.
Solution 2
You can throw a CustomException and map it to a CustomExceptionMapper to provide customized response.
public class CustomException extends RuntimeException {
public CustomException(Throwable throwable) {
super(throwable);
}
public CustomException(String string, Throwable throwable) {
super(string, throwable);
}
public CustomException(String string) {
super(string);
}
public CustomException() {
super();
}
}
@Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {
private static Logger logger = Logger.getLogger(CustomExceptionMapper.class.getName());
/**
* This constructor is invoked when exception is thrown, after
* resource-method has been invoked. Using @provider.
*/
public CustomExceptionMapper() {
super();
}
/**
* When exception is thrown by the jersey container.This method is invoked
*/
public Response toResponse(CustomException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
Response.ResponseBuilder resp = Response.status(Response.Status.BAD_REQUEST)
.entity(ex.getMessage());
return resp.build();
}
}
Use the CustomException in your code like this.
public Entity getEntityWithOptions(@PathParam("id") String id,
@QueryParam("option") String optValue)
throws CustomException {
if (optValue != null) {
// Option is an enum
try {
Option option = Option.valueOf(optValue);
} catch (IllegalArgumentException e) {
throw new CustomException(e.getMessage(),e);
}
return new Entity(option);
}
return new Entity();
}
Instead of message, you can also construct an object and pass it to mapper through CustomException.
Related videos on Youtube
dabadaba
Updated on June 04, 2022Comments
-
dabadaba almost 2 years
Is it possible to include a message in a
BadRequestException
so when the user sees a response code a 400, he/she can also figure out why?The scenario would be something like this, simplified:
public Entity getEntityWithOptions(@PathParam("id") String id, @QueryParam("option") String optValue) { if (optValue != null) { // Option is an enum try { Option option = Option.valueOf(optValue); } catch (IllegalArgumentException e) { throw new BadRequestException(e.getMessage()); } return new Entity(option); } return new Entity(); }
I know this can be done returning a
Response
object instead, but I wouldn't want that.Is this possible? Maybe with an
ExceptionMapper<BadRequestException>
? Or this cannot be done sinceBadRequestException
is already a Jersey-specific exception?-
Cuero almost 8 yearsI think the message can be put into the constructor, right? And If an exceptionMapper is used, it actually returns a Response.
-
dabadaba almost 8 yearsI am passing the message to the constructor, but the response is not including it.
-
Cuero almost 8 yearsIf an exceptionMapper is used, the message passed to the constructor is displayed. Just make the mapper like this: public Response toResponse(BadRequestException e) { return Response.status(Response.Status.BAD_REQUEST).type(MediaType.TEXT_PLAIN).entity(ExceptionUtils.getStackTrace(e)).build();}
-
cs_pupil about 3 yearsThis worked for me: stackoverflow.com/q/30712454/3806701
-