有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在jersey中以编程方式注册提供程序,该提供程序实现exceptionmapper

我如何在jersey中以编程方式注册我的提供者,它实现了jersey API提供的Exceptionmapper?我不想使用@Provider注释,而是想使用ResourceConfig注册提供程序,我该怎么做

例如:

public class MyProvider implements ExceptionMapper<WebApplicationException> extends ResourceConfig {

     public MyProvider() {
        final Resource.Builder resourceBuilder = Resource.builder();
        resourceBuilder.path("helloworld");

        final ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod("GET");
        methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE)
                .handledBy(new Inflector<ContainerRequestContext, String>() {

            @Override
            public String apply(ContainerRequestContext containerRequestContext) {
                return "Hello World!";
            }
        });

        final Resource resource = resourceBuilder.build();
        registerResources(resource);
    }

    @Override
    public Response toResponse(WebApplicationException ex) {
        String trace = Exceptions.getStackTraceAsString(ex);
        return Response.status(500).entity(trace).type("text/plain").build();
    }
}

这是正确的方法吗


共 (3) 个答案

  1. # 1 楼答案

    如果您正在使用Spring,并且希望基于@Path@Provider注释的存在以编程方式注册提供程序,那么可以使用以下技术

    @Component
    public class JerseyConfig extends ResourceConfig {
    
      @Autowired
      private ApplicationContext applicationContext;
    
      @PostConstruct
      public init() {
    
        applicationContext.getBeansWithAnnotation(Path.class).values().forEach(
          component -> register(component.getClass())
        );
        applicationContext.getBeansWithAnnotation(Provider.class).values().forEach(
          this::register
        );
      }
    }
    
  2. # 2 楼答案

    我猜你没有ResourceConfig,因为你似乎不知道如何使用它。首先,它不是必需的。如果你使用它,它应该是它自己的独立类。在那里你可以注册地图绘制者

    public class AppConfig extends ResourceConfig {
        public AppConfig() {
            register(new MyProvider());
        }
    }
    

    但你可能正在使用网络。xml。在这种情况下,您可以使用以下<init-param>注册提供者

    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>
                org.foo.providers.MyProvider
            </param-value>
        </init-param>
    </servlet>
    

    有关不同部署模型的更多信息,请查看What exactly is the ResourceConfig class in Jersey 2? 。部署应用程序有几种不同的方法。你甚至可以混合搭配(web.xml和ResourceConfig)

  3. # 3 楼答案

    尽管@paul samsotha的答案是正确的,但仍然存在实现技巧。我想分享它,希望它能帮助别人

    a)实现映射器:

    public class MyExceptionMapper implements ExceptionMapper<Throwable>, ResponseErrorMapper {
        ...
    

    b)确保声明泛型类型,否则将永远不会调用映射程序

    public class MyExceptionMapper implements ExceptionMapper/* no generic declaration */, ResponseErrorMapper {
        ...
    

    并可能引发

    javax.ws.rs.ProcessingException: Could not find exception type for given ExceptionMapper class: class com...MyExceptionMapper.
    

    c)将其注册为资源:

    ResourceConfig config = new ResourceConfig();
    config.register(new MyExceptionMapper());
    

    或者

    config.register(MyExceptionMapper.class);
    

    d)还要确保执行处理错误:

    config.setProperties(new LinkedHashMap<String, Object>() {{
        put(org.glassfish.jersey.server.ServerProperties.PROCESSING_RESPONSE_ERRORS_ENABLED, true);
    }});