私は、RESTのWebサービスを開発しています。シリアライズ/デシリアライゼーションのためのJAX-RSプロバイダーとジャクソンなどジャージー。私はまた、Retrofit2に基づいてクライアントを開発しています。
私のクラス階層は、サードパーティのライブラリで提供されており、すべてのクラスは、ルートベースクラスから派生しますBaseObject
。これらのクラスの中には、例えば、望ましくないゲッターを持ってisEmpty
、私は(彼らがすべてでシリアライズされませんし、使用していることが重要であることに注意してくださいシリアライズに無視すること、FAIL_ON_UNKNOWN_PROPERTIES
逆シリアル化の上では私の場合には十分ではありません)。
私はジャクソンを使用している@JsonFilter
上でBaseClass
ミックスインを使用します。フィルタを適用するには、私の知る限りでは、一つは以下を使用することがあります。
new ObjectMapper().writer(filterProvider).writeValueAsString...
すべてはここにOKをアップしている:望ましくないプロパティが正常に作成JSONから濾過されます。
今、私は私のカスタマイズされたJSONシリアライザ/デシリアライザを使用するようにジャージとRetrofit2を設定する必要があります。
ジャージーため、シリアライズ/デシリアライズを用いて構成することができるProvider
実装するクラスContextResolver<ObjectMapper>
と復帰がカスタマイズObjectMapper
にgetContext(Class<?> type)
方法。
同様にRetrofit2に、使用することによってRetrofit.Builder().addConverterFactory(JacksonConverterFactory.create(objectMapper))
、一つはシリアライズ/デシリアライゼーションのをカスタマイズすることができます。
問題は、IS new ObjectMapper().writer(filterProvider)
型のものでObjectWriter
はないタイプのObjectMapper
。どのように私は自分のカスタマイズに使用するジャージーとRetrofit2を伝えることができObjectWriter
、私のフィルタを使用していますか?
ジャクソンのバージョン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-。あなたは説明があなたのケースのために収まるので、私は考えて試すことができます。
私はジャージー2.7とジャクソン2.9.5でテストサービスを構築しました。それが正常に動作しますが、あなたはそれを実行するためにいくつかのトリックを知っている必要があります。
pom.xmlでジャージーとジャクソンを追加します。
<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>
MyApplication.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を登録する必要が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」メソッドを使用します。この方法は推奨されませんが、「ジャージ-HK2」と呼ばれるジャージーのライブラリは、新しいメソッド「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();
}
}
フィルタリングされた結果: