RestEasyエンドポイントから出力されるデフォルトのJackson JSONを美化するように求められました。私はジャクソンについていくつかの調査を行い、nullの抑制、データ形式のカスタマイズなどができるようにいくつかのスタンドアロンコードを作成しました。ここでの課題は、このコードをRestEasyのJSONシリアル化に挿入することです。
フォーラムの投稿から判断すると、これはSpringでは取るに足らないことですが、RestEasyではそうではないようです。私はContextResolverを記述し、web.xml(Tomcat上)のcontext paramsでresteasy.providerとして構成しましたが、これにより、webappがTomcatにロードされなくなります。
今、私はjavax.ws.rs.core.Applicationを拡張してContextResolverを提供しようとしていますが、何も進歩していません。これは簡単です、誰かこれをしましたか?どんな助けでも大歓迎です。
わかりました、私は Jackson FAQ:JAX-RS に基づいてカスタムJacksonJsonProviderを記述することでこれを行うことができました。コードは次のとおりです。
@Provider
public class QBOJacksonJsonProvider extends JacksonJsonProvider {
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
@Override
public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String,Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
Log.info(getClass(), "In custom JSON provider");
//get the Object Mapper
ObjectMapper mapper = locateMapper(type, mediaType);
// Suppress null properties in JSON output
mapper.getSerializationConfig().setSerializationInclusion(org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_NULL);
// Set human readable date format
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
mapper.getSerializationConfig().setDateFormat(sdf);
super.writeTo(value, type, genericType, annotations, mediaType, httpHeaders, entityStream);
}
}
Jackson SerializationConfigを変更するより良い方法を見つけました-JAX-RS ContextResolverを使用してObjectMapperの作成をインターセプトできます。
@Provider
@Produces(Array(MediaType.APPLICATION_JSON))
class JacksonConfig extends ContextResolver[ObjectMapper] {
val mapper = new ObjectMapper()
mapper.getSerializationConfig.setSerializationInclusion(Inclusion.NON_NULL)
def getContext(objectType: Class[_]) = mapper
}
以下のいずれかの方法でRESTEasyに登録する必要があります。
リファレンス: RESTEasy docs
参照: JBossフォーラムのNicklas Karlsson
これは、JBoss 7.1.1.Finalのモジュールとして出荷されるRESTEasy 2.3.2で機能しますが、RESTEasy 3.0-beta5では機能しないようです。
Jackson2プロバイダーを使用している場合は、前の回答とは少し異なる方法を実行する必要があります。この例では、デフォルトで出力をきれいに出力します
@Provider
public class JSONProvider extends ResteasyJackson2Provider {
@Override
public void writeTo(Object value, Class<?> type, Type genericType, Annotation[] annotations, MediaType json, MultivaluedMap<String, Object> headers, OutputStream body) throws IOException {
ObjectMapper mapper = locateMapper(type, json);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
super.writeTo(value, type, genericType, annotations, json, headers, body);
}
}
自動登録を有効にしていない場合は、web-xmlに登録して、resteasy.providers context-paramに追加します。
Jackson ObjectMapper
のプロバイダーは、これを行う標準のJAX-RSの方法である必要があるため(Jerseyで動作します)、RESTeasyでも同様に使用できるようです。
Spring Bootを使用してweb.xmlを使用していない場合、context-paramを使用するためのヒントに従っても、アプリケーションに登録するのに多くの作業がありましたが、ここでは
カスタムプロバイダー
package com.mageddo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
@Provider
@Consumes({"application/json", "application/*+json", "text/json"})
@Produces({"application/json", "application/*+json", "text/json"})
public class CustomJacksonJsonProvider extends ResteasyJackson2Provider {
private ObjectMapper objectMapper = new ObjectMapper(); // my own object mapper
@Override
public ObjectMapper locateMapper(Class<?> type, MediaType mediaType) {
return objectMapper;
}
}
アプリケーションへの登録
META-INF/services/javax.ws.rs.ext.Providers
com.mageddo.CustomJacksonJsonProvider
org.jboss.resteasy.plugins.providers.jackson.UnrecognizedPropertyExceptionHandler
Jackson 2.2.xプロバイダーを使用している場合、ResteasyはJAXBプロバイダーのそれに類似したきれいに印刷するアノテーションを提供しています。
org.jboss.resteasy.annotations.providers.jackson.Formatted
次に例を示します。
@GET @Produces("application/json") @Path("/formatted/{id}") @Formatted public Product getFormattedProduct() { return new Product(333, "robot"); }
上記の例のように、@ Formattedアノテーションは、基になるJacksonオプション "SerializationFeature.INDENT_OUTPUT"を有効にします。
© RESTEasyユーザーガイド 。
これはグローバルなソリューションではありませんが、アノテーションをクラスに置くこともできます。