Reputation: 619
Am writing a Restful Webservice Impl, where i consume and produce response in JSON format by annotating @Produces("application/json")
. Am producing JSON response as well. Here am handling exception with a class where it has error code and error message. When am getting exception it is not produced in application/json
format. I used ExceptionMapper
to find a solution but it is `text/plain format.
snippet
public Class Confiuration{
@Path("getData")
@Consumes("application/json")
@Produces("application/json")
public JSONGetDataResponseVo getData(GetDataRequestVo datarequestVO)
throws FaultResponse {
JSONGetDataResponseVo response=new JSONGetDataResponseVo ();
DataServiceValidator.validateGetConfigurationAndDataRequest(datarequestVO);
....
....
}catch(ApplicationException applicationException){
throw new FaultResponse(applicationException,locale);
}
}
FaultResponseMapper
@Provider
public class FaultResponseMapper implements ExceptionMapper<FaultResponse> {
@Context
private HttpHeaders headers;
public Response toResponse(FaultResponse faultResponse) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(faultResponse).type(MediaType.APPLICATION_JSON).build();
}
}
Application Exception
public abstract class ApplicationException extends Exception{
private java.lang.String errorCode;
public ApplicationException(String errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public ApplicationException(String message) {
super(message);
}
public java.lang.String getErrorCode() {
return this.errorCode;
}
public abstract String getLocaleMessage(Locale locale);
}
FaultResponse
public class FaultResponse extends WebApplicationException {
private String errorCode;
private String errorMessage;
private String localErrorMessage;
public FaultResponse(String errorCode, String errorMessage,
String localErrorMessage) {
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.localErrorMessage = localErrorMessage;
}
public FaultResponse(ApplicationException applicationException,
Locale locale) {
this.errorCode = applicationException.getErrorCode();
this.errorMessage = applicationException.getMessage();
if (locale != null
&& applicationException.getLocaleMessage(locale) != null) {
this.localErrorMessage = applicationException
.getLocaleMessage(locale);
} else {
this.localErrorMessage = applicationException.getMessage();
}
}
}
So here how can i produce my faultResponse in JSON format.
Upvotes: 1
Views: 2114
Reputation: 208994
This has to do with the fact that you are returning an exception as a response. I would
ApplicationException
.FaultResponse
to not extend and exception. Just create it in the mapper.throws ApplicationException
. You don't need to catch it and rethrow.I've made these changes, and it works fine.
Added getters (required for marshalling) to FaultResponse
and remove the exception extension
public class FaultResponse {
...
public String getErrorCode() { return errorCode; }
public String getErrorMessage() { return errorMessage; }
public String getLocalErrorMessage() { return localErrorMessage; }
...
}
Created a Service for testing and ApplicationException
implementation
public class ApplicationExceptionImpl extends ApplicationException {
public ApplicationExceptionImpl(){
this("400", "Bad Request");
}
public ApplicationExceptionImpl(String errorCode, String message) {
super(errorCode, message);
}
@Override
public String getLocaleMessage(Locale locale) {
return "Bad Request";
}
}
public class FaultService {
public void doSomething() throws ApplicationException {
throw new ApplicationExceptionImpl();
}
}
Resource class
@Path("fault")
public class FaultResource {
FaultService service = new FaultService();
@GET
public Response getException() throws ApplicationException {
service.doSomething();
return Response.ok("Cool").build();
}
}
ExceptionMapper
@Provider
public class ApplicationExceptionMapper implements ExceptionMapper<ApplicationException> {
@Override
public Response toResponse(ApplicationException exception) {
FaultResponse response = new FaultResponse(exception, Locale.ENGLISH);
return Response.status(Response.Status.BAD_REQUEST)
.entity(response).type(MediaType.APPLICATION_JSON).build();
}
}
ApplicationException class is left the same
curl -v http://localhost:8080/api/fault
{"errorCode":"400","errorMessage":"Bad Request","localErrorMessage":"Bad Request"}
If after this you are still not seeing JSON, it's possible you do not have a provider configured. If this is the case, please show your application configuration, along with your project dependencies.
Upvotes: 1