7

アプリケーションに JAXRS エンドポイントを提供するために、IBM(s) にバンドルされている Apache Wink を使用しています。Websphere 8.5.5 に向けてコーディングしています。私たちはサーブレット 3.0 に準拠しているため、JaxRS アプリケーションを構成する「プログラムによる」方法を使用します。つまり、web.xml にエントリがなく、注釈付きの jax rs リソースのクラス スキャンに依存しています。一般的には正常に動作します。

   @ApplicationPath("/api/v1/") 
   public class MyApplication  extends Application{

このバージョンの Websphere と Apache Wink は、JSON のデシリアライゼーションに Jackson 1.6.x を使用しており、一般的にはうまく機能します。Object Mapper のデフォルト値のいくつかを変更したいと思います

そのため、se/deserialzation プロパティの一部を変更するだけの顧客コンテキスト リゾルバーを定義しました。

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class CustomJackssonConverter implements ContextResolver<ObjectMapper> {

    final ObjectMapper defaultObjectMapper;

    public AibasJackssonConverter() {
        defaultObjectMapper = createDefaultMapper();
    }
   ...       
 mapper.getSerializationConfig().set(SerializationConfig.Feature.INDENT_OUTPUT, true);

JAX-RS 呼び出し中に、コンテナーが新しいプロバイダーをエラーなしで登録していることを確認できます。

問題は、構成が「フォロー」されていないことです。ログから、Wink Engine が WinkJacksonProvider を検索していることがわかります。WinkJacksonProvider は、Jackson(s) のデフォルト値に従っている JacksonProvider を返します。

このデフォルト値を変更する方法はありますか?

プロバイダーをプログラムで構成するために、ここに示されているように Application オブジェクトの実装を変更しようとしましたが、うまくいきませんでした。

http://www.ibm.com/developerworks/java/library/wa-aj-jackson/index.html

ヒントやヒントはありますか?

どうもありがとう

4

4 に答える 4

3

次のように MessageBodyWriter クラスを実装するだけで、この問題を解決しました。

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class DefaultMessageBodyWriter implements MessageBodyWriter<Object> {

    @Override
    public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return true;
    }

    @Override
    public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
        mapper.writeValue(entityStream, object);
    }
}

JSON シリアル化が要求されるたびに、このクラスが実行され、最後にその writeTo メソッドが呼び出されます。

ここで、SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS は、WebSphere からの要求に従ってオフになっています。

于 2015-12-18T19:08:00.413 に答える
-1

WAS v8.0.0.x では、Jackson の代わりに MOXy を使用しています。

Jackson をオーバーライドするために、次のように Application クラスを実装します。

@Named
@ApplicationScoped
@ApplicationPath("/resources/")
public class WinkApplication extends Application implements Serializable {

private static final long serialVersionUID = 1L;

@Override
public Set<Class<?>> getClasses() {
    Set<Class<?>> classes = new HashSet<Class<?>>();
    classes.add(WinkResource.class);
    classes.add(WinkMOXyJsonProvider.class);
    classes.add(WinkResponseException.class);
    classes.add(WinkResponseExceptionMapper.class);
    return classes;
}
}

ただし、WAS が次の注釈を無視しているように見えることに気付きました。

@ApplicationPath("/resources/")

そのため、web.xml を使用することにしました。

<!-- Wink Servlet -->
<servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.company.team.project.webservices.config.WinkApplication</param-value>
    </init-param>
    <!-- <init-param>
        <param-name>propertiesLocation</param-name>
        <param-value>/WEB-INF/my-wink-properties.properties</param-value>
    </init-param> -->
    <load-on-startup>1</load-on-startup>
    <enabled>true</enabled>
    <async-supported>false</async-supported>
</servlet>

<!-- Wink Servlet Mapping -->
<servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
</servlet-mapping>

要点は、ApplicationPath アノテーションを使用する場合、WAS または Wink は Application 実装を無視するように見えるため、Wink はデフォルトで Jackson を使用するデフォルトの Application クラスをロードするということです。

はい、ドキュメントを読んだり、@ApplicationPath を使用すると XML 構成を回避できることを述べている IBM ビデオをオンラインで見たりしましたが、この問題はバグのようです。

アップデート:

別のアプローチは、David Blevins が別の SO 投稿で言及したものである可能性があります。

セクション JAX-RS の使用を確認してください。

于 2015-03-20T08:49:51.257 に答える