I have an AngularJS client trying to consume a REST Web Service on Wildfly. It works when the server returns an object, but when an exception is thrown, I'm getting the following message:
XMLHttpRequest cannot load http://localhost:8080/ProdutosBackend-0.0.1-SNAPSHOT/rest/user/create. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:51647' is therefore not allowed access. The response had HTTP status code 500.
I tried lots of combinations of headers and filters, but nothing can make this works.
Client code:
var user = {
email : $scope.signUpData.email,
password : $scope.signUpData.password,
name : $scope.signUpData.name
};
$http.post(
'http://localhost:8080/ProdutosBackend-0.0.1-SNAPSHOT/rest/user/create',
user).
then(function(data) {
console.log("It works!");
},
function(response) {
console.log(response);
});
Web Service
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import br.com.produtos.business.UserBO;
import br.com.produtos.business.exceptions.BusinessException;
import br.com.produtos.entity.User;
import br.com.produtos.transaction.Transaction;
@Path("/user")
public class UserREST {
@POST
@Path("/create")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({ MediaType.APPLICATION_JSON })
public User createAcount(@Context HttpServletRequest httpServletRequest, User user) throws BusinessException {
if (user.getEmail().equals("fff")) {
throw new BusinessException("Bussiness error.");
}
{...}
return user;
}
}
ExceptionMapper
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
public class ThrowableMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable throwable) {
return Response.status(500).entity(throwable.getMessage()).build();
}
}
Application
@ApplicationPath("/rest")
public class ThisApplication extends Application {
public static CorsFilter cors;
private Set<Object> singletons = new HashSet<Object>();
private Set<Class<?>> empty = new HashSet<Class<?>>();
public ThisApplication() {
CorsFilter filter = new CorsFilter();
filter.getAllowedOrigins().add("*");
cors = filter;
singletons.add(filter);
singletons.add(new ThrowableMapper());
singletons.add(new UserREST());
}
public Set<Class<?>> getClasses() {
return empty;
}
public Set<Object> getSingletons() {
return singletons;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ProdutosBackend</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>br.com.produtos.rest.ThisApplication</param-value>
</context-param>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I solved the problem returning the message encapsulated into a json string.
public class ThrowableMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable throwable) {
return Response.status(500).entity("{ \"message\": \"" + throwable.getMessage() + "\" }").build();
}
}