gpt4 book ai didi

java - 将自定义的 ObjectWriter 与 Jersey 一起使用

转载 作者:搜寻专家 更新时间:2023-11-01 03:31:04 24 4
gpt4 key购买 nike

我正在开发 REST 网络服务。 Jersey 作为 jax-rs 提供者和 Jackson 用于序列化/反序列化。我也是基于Retrofit2开发客户端。

我的类层次结构由第三方库提供,所有类都派生自根基类 BaseObject .其中一些类有不受欢迎的 setter/getter ,例如isEmpty ,我想忽略序列化(请注意,重要的是它们根本不被序列化,并且在我的情况下使用 FAIL_ON_UNKNOWN_PROPERTIES 反序列化是不够的)。

我用过 jackson @JsonFilterBaseClass使用混合。据我所知,要应用过滤器,必须使用以下内容:

new ObjectMapper().writer(filterProvider).writeValueAsString...

到目前为止一切正常:不需要的属性已从生成的 json 中成功过滤。

现在我必须配置 Jersey 和 Retrofit2 以使用我自定义的 json 序列化器/反序列化器。

对于 Jersey,可以使用 Provider 配置序列化/反序列化实现 ContextResolver<ObjectMapper> 的类并返回定制 ObjectMappergetContext(Class<?> type)方法。

与 Retrofit2 类似,通过使用 Retrofit.Builder().addConverterFactory(JacksonConverterFactory.create(objectMapper)) ,可以自定义序列化/反序列化。

问题是 new ObjectMapper().writer(filterProvider)类型为 ObjectWriter而不是 ObjectMapper 类型.我怎样才能告诉 Jersey 和 Retrofit2 使用我定制的 ObjectWriter哪个使用我的过滤器?

最佳答案

从 Jackson 的 2.6 版开始,它为 ObjectMapper 提供了“setFilterProvider”方法。我没试过,但文档对此有描述:https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/ObjectMapper.html#setFilterProvider-com.fasterxml.jackson.databind.ser.FilterProvider- .我认为您可以尝试,因为描述适合您的情况。

我使用 Jersey 2.7 和 Jackson 2.9.5 构建了一个测试服务。它工作正常,但您必须知道一些技巧才能运行它。

在 pom.xml 中添加 Jersey 和 Jackson:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.7</jersey.version>
<jackson.version>2.9.5</jackson.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

你必须定义这个依赖:

    <dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>

这是强制性的。

在 web.xml 中,您必须对服务的配置进行引用:

<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>org.glassfish.jersey.server.ResourceConfig</param-name>
<param-value>com.home.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

我的应用程序.java:

package com.home;

import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;

import javax.ws.rs.ApplicationPath;

@ApplicationPath("/webapi")
public class MyApplication extends ResourceConfig {

public MyApplication() {

register(ObjectMapperProvider.class);
register(JacksonFeature.class);
register(MyResource.class);

}
}

使用自定义 ObjectMapperProvider,您必须注册 JacksonFeature.class,因为没有它,Jersey 不会使用自定义 ObjectMapperProvider。

ObjectMapperProvider.java:

package com.home;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper>{

final ObjectMapper defaultObjectMapper;

public ObjectMapperProvider() {
defaultObjectMapper = createDefaultMapper();
}

@Override
public ObjectMapper getContext(Class<?> type) {return defaultObjectMapper;}

public static ObjectMapper createDefaultMapper() {

final ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setFilters(new SimpleFilterProvider().addFilter("dataFilter", SimpleBeanPropertyFilter.serializeAllExcept("region", "city")));
return mapper;

}
}

要定义过滤器,请使用“setFilters”方法。此方法已弃用,但名为“jersey-hk2”的 Jersey 库不知道新方法“setFilterProvider”并抛出异常。使用旧方法一切正常。

带有@JsonFilter 的业务对象:

@JsonFilter("dataFilter")
public class SimpleData {

@JsonProperty("name")
String firstName;

@JsonProperty("secondName")
String lastName;

@JsonProperty("country")
String country;

@JsonProperty("region")
String region;

@JsonProperty("city")
String city;

@JsonProperty("genre")
String genre;

public SimpleData() {

this.firstName = "Bryan";
this.lastName = "Adams";

this.country = "Canada";
this.region = "Ontario";
this.city = "Kingston";
this.genre = "Rock";

}

public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getCountry() { return country; }
public void setCountry(String country) { this.country = country; }
public String getRegion() { return region; }
public void setRegion(String region) { this.region = region; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getGenre() { return genre; }
public void setGenre(String genre) { this.genre = genre; }
}

MyResource.java:

@Path("myresource")
public class MyResource {


@GET
@Produces(MediaType.APPLICATION_JSON)
public SimpleData getIt() {

return new SimpleData();

}
}

过滤后的结果:

enter image description here

关于java - 将自定义的 ObjectWriter 与 Jersey 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55103045/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com