泽西岛的主要收录服务提供商

And*_*rew 5 java jersey jackson

我需要在Jersey中创建一个自定义ExceptionMapper来处理Jackson返回的JsonProcessingException。

Jackson库已经以JsonMappingExceptionMapper.java和JsonParseExceptionMapper.java(link)的形式包含此异常的ExceptionMapper提供程序。

如果在“ my.package”中为此异常映射器添加新的提供程序,则有关所选提供程序的结果将无法预测。有时它将选择“ my.package”中的提供程序,有时它将选择Jackson库中的提供程序。下面是我用来扫描软件包的代码。

PackgesResourceConfig packagesResourceConfig = new PackgesResourceConfig("com.fasterxml.jackson.jaxrs", "my.package");
Run Code Online (Sandbox Code Playgroud)

拟议的解决方案

目前,我正在通过手动过滤掉Jackson库中的提供程序来解决此问题。但是我真正想知道的是,是否有一种更可接受和更受支持的方式来执行此操作。

首先,我扩展PackagesResourceConfig。

public class FilteredPackgesResourceConfig extends PackagesResourceConfig {

    private Set<Class<?>> classesToFilter = new HashSet<Class<?>>();

    public FilteredPackgesResourceConfig(String... packages) {
        super(packages);
    }

    public FilteredPackgesResourceConfig(Map<String, Object> props) {
        super(props);
    }

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = super.getClasses();

        if (classes != null && classesToFilter != null) {
            classes.removeAll(classesToFilter);
        }

        return classes;
    }

    public Set<Class<?>> getClassesToFilter() {
        return classesToFilter;
    }

    public void setClassesToFilter(Set<Class<?>> classesToFilter) {
        this.classesToFilter = classesToFilter;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用此类来过滤掉不需要的特定提供程序。

FilteredPackgesResourceConfig packagesResourceConfig = new FilteredPackgesResourceConfig("com.fasterxml.jackson.jaxrs", "my.package");
classesToFilter.add(com.fasterxml.jackson.jaxrs.json.JsonMappingExceptionMapper.class);       
classesToFilter.add(com.fasterxml.jackson.jaxrs.json.JsonParseExceptionMapper.class);
packagesResourceConfig.setClassesToFilter(classesToFilter);
Run Code Online (Sandbox Code Playgroud)

此解决方案仅使用我指定的提供程序即可为我提供所需的结果。有没有更正确的方法来达到相同的结果?

小智 4

我也遇到了这个问题,在我的例子中,我通过不注册com.fasterxml.jackson.jaxrs.json包来解决它,而是只注册了我想要的类,在我的例子中是com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.

有几种方法可以做到这一点,我使用 web.xml 来做到这一点,如下所示:

<servlet>
  <servlet-name>jersey-serlvet</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>
         my.own.package
         my.other.package
      </param-value>
  </init-param>
  <init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
      com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
    </param-value>
  </init-param>
    <init-param>
      <param-name>jersey.config.disableMoxyJson</param-name>
      <param-value>true</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)

注意:我使用的是 Jersey 2.0,在 1.x 中,属性名称和 servlet 类不同,但可以使用相同的配置。