2014-05-05 12 views
6

Chúng tôi đang sử dụng (các) IBM kèm theo Apache Wink để cung cấp các điểm cuối JAXRS cho ứng dụng của chúng tôi. Chúng tôi đang mã hóa theo hướng Websphere 8.5.5. Vì chúng ta tuân thủ servlet 3.0, chúng ta sử dụng cách 'lập trình' để cấu hình ứng dụng JaxRS, có nghĩa là không có mục nào trong web.xml và chúng ta dựa vào quét lớp cho các tài nguyên rs jax có chú thích. Nói chung nó hoạt động tốt.Ghi đè lên các thuộc tính của Trình ánh xạ đối tượng Jackson trên Websphere 8.5.5 bằng cách sử dụng Apache Wink

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

Phiên bản Websphere này cùng với Apache Wink, sử dụng Jackson 1.6.x cho JSON de/serialization và nói chung nó hoạt động tốt. Mặc dù chúng tôi muốn thay đổi một số giá trị mặc định của Object Mapper

Vì vậy, chúng tôi đã xác định giải pháp ngữ cảnh của khách hàng, nơi chỉ thay đổi một số thuộc tính 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); 

Trong cuộc gọi JAX-RS chúng ta có thể thấy rằng container đăng ký nhà cung cấp mới, không có lỗi

Vấn đề là, Configuration không 'tiếp', từ các bản ghi tôi có thể thấy rằng Wink Engine đang tìm kiếm một WinkJacksonProvider, mà lần lượt .. trả lại một JacksonProvider đang theo các giá trị mặc định của Jackson?

Có cách nào để thay đổi giá trị mặc định này không?

Tôi đã cố gắng thay đổi việc triển khai đối tượng Ứng dụng như được nêu ở đây, để định cấu hình Nhà cung cấp theo chương trình, nhưng nó không hoạt động.

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

Bất kỳ gợi ý hay mẹo nào?

Rất cám ơn

+0

Bạn đã thử diễn đàn WebSphere chưa? http://ibm.biz/websphere-forum – dbreaux

+0

Tôi không thể làm việc này. Khi tôi bao gồm một JacksonJsonProvider trong ứng dụng getClasses(). Websphere sẽ sử dụng Jackson. Nhưng không có cách nào để tùy chỉnh Jackson. Nếu tôi thay vào đó bao gồm một tùy chỉnh cấu hình JacksonJsonProvider trong ứng dụng getSingletons(). Websphere sẽ không sử dụng nó. Không có đối tượng Response (hoặc payload) của chúng được serialized. Phương thức REST sẽ trả về một phần thân trả về không có gì. (Cuộc sống dễ dàng hơn nhiều với TomcatEE.) – devdanke

Trả lời

-1

Tôi sử dụng MOXy thay vì Jackson trong WAS v8.0.0.x.

Để ghi đè Jackson, tôi thực hiện lớp ứng dụng của tôi như vậy:

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

Tuy nhiên, tôi đã nhận thấy rằng WS dường như bỏ qua chú thích sau:

@ApplicationPath("/resources/") 

Vì vậy, tôi đã viện để sử dụng 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> 

Vấn đề là vì WAS hoặc Wink có vẻ bỏ qua ứng dụng Triển khai entation khi sử dụng chú thích ApplicationPath, Wink tải lớp ứng dụng mặc định, sử dụng Jackson theo mặc định.

Và có, tôi đã đọc tài liệu và thậm chí xem video trực tuyến của IBM đề cập đến @ApplicationPath cho phép bạn tránh cấu hình XML, tuy nhiên vấn đề này có vẻ là một lỗi.

UPDATE:

Một phương pháp khác có thể là những gì David Blevins đã đề cập trong một bài SO.

Check out the section Using JAX-RS

+0

Hãy thử sử dụng bộ xử lý JSON JSON với EJB được chú thích bằng "@Path" và "@WebService". Đó là giải pháp thay thế được đề cập trong phần JAX-RS. Nó có thể cho phép bạn bỏ qua việc triển khai ứng dụng JAX-RS thiếu sót của WAS. –

2

tôi giải quyết vấn đề này bằng cách chỉ thực hiện một lớp MessageBodyWriter, như thế này:

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

Mỗi khi một serialization JSON được yêu cầu, lớp này có hiệu hành động và cuối cùng là phương pháp writeTo của nó được gọi .

Tại đây SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS bị tắt, theo yêu cầu của WebSphere.

Các vấn đề liên quan