2014-05-05 57 views
6

我們使用IBM捆綁的Apache Wink爲我們的應用程序提供JAXRS端點。我們正在編寫Websphere 8.5.5。由於我們符合servlet 3.0,所以我們使用'編程'方式來配置JaxRS應用程序,這意味着web.xml中沒有條目,並且我們依賴於對帶註釋的jax rs資源進行類掃描。一般來說,它工作正常。使用Apache Wink覆蓋Websphere 8.5.5上的Jackson Object Mapper屬性

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

此版本的WebSphere和Apache Wink一起,​​使用傑克遜1.6.x版的JSON德/序列化和一般的效果很好。我們希望儘管改變一些對象映射器的默認值

因此,我們定義了一個客戶上下文解析器,其中只是改變一些序列/反序列化屬性。

@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引擎正在查找一個WinkJacksonProvider,它反過來會返回一個遵循Jackson(s)默認值的JacksonProvider?

有沒有辦法改變這個默認值?

我試圖改變應用程序對象的實現,如此處所示,以便以編程方式配置提供程序,但它不起作用。

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

任何提示或建議?

非常感謝

+0

您是否試過WebSphere論壇? http://ibm.biz/websphere-forum – dbreaux

+0

我也無法讓這個工作。當我在Application getClasses()中包含一個JacksonJsonProvider時。 Websphere將使用Jackson。但是沒有辦法定製傑克遜。如果我在Application getSingletons()中包含一個自定義配置的JacksonJsonProvider。 Websphere不會使用它。沒有響應對象(或其有效載荷)被序列化。應該返回響應主體的REST方法不返回任何內容。 (使用TomcatEE,生活變得如此簡單。) – devdanke

回答

-1

我USSE莫西,而不是傑克遜在WAS v8.0.0.x.

要覆蓋傑克遜,我實現了我的應用程序類像這樣:

@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; 
} 
} 

然而,我注意到,這是似乎忽略了以下注釋:

@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> 

問題是,既然WAS或Wink似乎忽略了應用程序實現當使用ApplicationPath註釋時,Wink會加載缺省的Application類,該類默認使用Jackson。

是的,我已閱讀文檔,甚至在線觀看IBM視頻,提及@ApplicationPath允許您避免XML配置,但這個問題似乎是一個錯誤。

UPDATE:

另一種做法可能是什麼大衛Blevins在另一個SO後已經提及。

Check out the section Using JAX-RS

+0

嘗試將Jackson JSON處理器與註釋爲「@Path」和「@WebService」的EJB結合使用。這是JAX-RS部分提到的替代方案。它可能允許您繞過WAS有缺陷的JAX-RS應用程序實現。 –

2

我剛好實現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的要求。