ExerseyMapper中的toResponse不会被调用

时间:2014-03-14 18:42:57

标签: java rest exception jersey provider

所以我正在构建一个Web应用程序,我们正在使用JPA和Jersey来使用/生成JSON数据。

我有一个自定义" EntityException"以及#34; EntityExceptionMapper"

这是映射器:

  @Provider
public class EntityExceptionMapper implements ExceptionMapper<EntityException> {

    public EntityExceptionMapper() {
        System.out.println("Mapper created");
    }

    @Override
    public Response toResponse(EntityException e) {
        System.out.println("This doesnt print!");
        return Response.serverError().build();
    }
}

我的例外:

public class EntityException extends Exception implements Serializable{

  public EntityException(String message) {
      super(message);
      System.out.println("This prints...");
  }

}

我从REST电话中调用它:

@POST
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
public String test() throws EntityException{
    throw new EntityException("This needs to be send as response!!");
    //return "test";
}

我的问题是,当抛出上述异常时,我进入构造函数(打印:&#34;这打印......&#34;)编辑:我也得到:&#34; Mapper创建!&#34;

但是我的回答是空的,我没有通过我的toResponse方法进入系统。这与球衣网站上的例子非常相似:

https://jersey.java.net/nonav/documentation/1.12/jax-rs.html#d4e435

我错过了什么?

10 个答案:

答案 0 :(得分:10)

我正在使用部署无关的应用程序模型,所以以下内容对我有用:

public class MyApplication extends Application {
    public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(HelloWorldResource.class);

        /** you need to add ExceptionMapper class as well **/
        s.add(EntityExceptionMapper.class)
        return s;
    }
}

答案 1 :(得分:4)

我遇到了类似的问题,其中ExceptionMapper有正确的@Provider注释,其余代码与泽西的示例相同,但仍然没有正确注册。< / p>

事实证明,我必须使用方法ExceptionMapper在我的HttpServlet中手动注册我的自定义addExceptionMapper。由于现在手动注册,因此可以安全地删除@Provider注释。

所以使用以下ExceptionMapper(我将每个RuntimeException捕获,将它们重新抛出为400)

public class MyCustomExceptionHandler implements ExceptionMapper<RuntimeException> {

  @Override
  public Response toResponse(RuntimeException exception) {
    return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
  }
}

我必须在我的init中添加第二行:

HttpServlet serviceServlet = jerseyServletFactory.create(someResource);
jerseyServletFactory.addExceptionMapper(new MyCustomExceptionHandler()); //<--

httpServer.register(serviceServlet, "/api");
httpServer.start();

答案 2 :(得分:2)

我遇到了同样的问题,并且能够通过在我的web.xml文件中的jersey.config.server.provider.packages中包含我的ExceptionMapper包来修复它。以下是我的web.xml的片段。

<servlet>
    <servlet-name>voteride-servlet</servlet-name>
    <servlet-class>
        org.glassfish.jersey.servlet.ServletContainer
    </servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
            com.voteride.ws;com.voteride.errorHandling;org.codehaus.jackson.jaxrs
        </param-value>
    </init-param>
    <init-param>
        <param-name>jersey.config.server.provider.scanning.recursive</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

答案 3 :(得分:2)

我在开发示例REST API时遇到了同样的问题。在创建REST API时,我已经给出了像org.manish.rest.message这样的基本包名, 我应该像这样

在基础包下创建其他所有包
  1. 型号 - org.manish.rest.message.model
  2. 数据库 - org.manish.rest.message.database
  3. 资源 - org.manish.rest.message.resource
  4. web.xml中的

    init param就像这样给出了

     <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>org.manish.rest.message</param-value>
     </init-param>
    

    这意味着,我已经在web.xml中注册了我的基础包,我将在此基础上创建什么包;将根据我的电话和要求由JAX-RS考虑。但是当我错误地创建我的异常包时,我将包名称org.manish.rest.exception。由于这未在web.xml中注册,因此我的完整异常类不被JAX-RS视为处理异常。 作为更正,我刚刚修改了我的异常包名称 org.manish.rest.exceptionorg.manish.rest.message.exception

    之后我在帖子中执行了一次,我得到了预期的结果。

    希望这可以解决您的疑问。

    由于 和Manish

答案 4 :(得分:1)

我用spring连接了jersey app并将@Component与@Provider一起使用。

当我搬到球衣v&gt; 2.5,它停止了工作。

我通过在@Provider旁边放置@Singleton注释而不是@Component解决了这个问题,如下所示:

@Provider
@Singleton
public class EntityExceptionMapper implements ExceptionMapper<EntityException> {...

答案 5 :(得分:1)

我正在使用Jersey JdkHttpServerFactory,我只需将ExceptionMapper类添加为资源,就像我的其他控制器资源一样:

import com.sun.net.httpserver.HttpServer;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.HashSet;
import java.util.Set;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

// ...

Set<Class> resources = new HashSet<>();
// Add whatever other resource classes you have...

//--->>> Add the exception mapper <<<---
resources.add(EntityExceptionMapper.class);

ResourceConfig resources = new ResourceConfig(resources);
URI uri = UriBuilder.fromUri("http://localhost/").build();
HttpServer server = JdkHttpServerFactory.createHttpServer(uri, resources);

答案 6 :(得分:1)

尝试在 X extends ResourceConfig 文件中注册您的异常映射器类。 的寄存器(CustomExceptionMapper.class); 这一行将帮助应用程序找到你的mapper类并返回你在mapper类的toResponse方法中编写的任何内容

答案 7 :(得分:0)

我仍然使用球衣1.17,弹簧和春天

@Component注释修复此

答案 8 :(得分:0)

我也面临同样的问题。只需添加包含ExceptionMappperHandler类的包名称。

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>Service,Utilities.ExceptionMapper</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

这里,service包含所有服务类,Utilities.ExceptionMapper包含所有exceptionMapper。 希望它的帮助

答案 9 :(得分:-1)

我遇到了同样的问题。我只需要修改web.xml。 以前在我的web.xml文件中,参数值为com.two95.restful.resource     我刚刚更改为root包com.two95.restful。然后它开始像只有@Provider注释的魅力一样工作。

<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.two95.restful</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>