ExceptionMapper 在处理异常时导致 "No 'Access-Control-Allow-Origin' header is present on the requested resource"

ExceptionMapper causes "No 'Access-Control-Allow-Origin' header is present on the requested resource" when handling an exception

我有一个 AngularJS 客户端试图在 Wildfly 上使用 REST Web 服务。 它在服务器 returns 和 object 时工作,但是当抛出异常时,我收到以下消息:

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.

我尝试了很多 headers 和滤镜的组合,但没有任何效果。

客户代码:

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);
  });

网络服务

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();
    }

}

申请

@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>

我解决了返回封装到 json 字符串中的消息的问题。

public class ThrowableMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable throwable) {
        return Response.status(500).entity("{ \"message\": \"" + throwable.getMessage() + "\" }").build();
    }

}