2014-05-05 15 views
6

Używamy dołączonego przez IBM Apache Wink do zaoferowania punktów końcowych JAXRS dla naszej aplikacji. Kodujemy do Websphere 8.5.5. Ponieważ jesteśmy zgodni z serwletem 3.0, używamy "programistycznego" sposobu konfigurowania aplikacji JaxRS, co oznacza brak wpisów w web.xml i polegamy na skanowaniu klas dla adnotowanych zasobów jax rs. Ogólnie rzecz biorąc działa dobrze.Zastępowanie właściwości obiektu Jackson Object Mapper na serwerze Websphere 8.5.5 za pomocą Apache Wink

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

Ta wersja Websphere wraz z Apache Wink, wykorzystuje Jackson 1.6.x dla JSON DE/serializacji i ogólnie działa dobrze. Chcielibyśmy jednak zmienić niektóre z domyślnych wartości Object Mappera:

Tak więc zdefiniowaliśmy klienta kontekstowego, który zmienia niektóre z właściwości 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); 

Podczas JAX-RS połączeń możemy zobaczyć, że pojemnik rejestruje nowego dostawcy, bez błędów

Problemem jest to, że konfiguracja nie jest „po”, z dzienników widzę, że Wink Engine szuka WinkJacksonProvider, który z kolei ... zwraca JacksonProvider, który śledzi domyślne wartości Jacksona?

Czy istnieje sposób na zmianę tej wartości domyślnej?

Próbowałem zmienić implementację obiektu aplikacji, jak wskazano tutaj, w celu programowego konfigurowania dostawców, ale nie zadziałało.

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

Wszelkie wskazówki lub porady?

Dziękujemy

+0

Czy próbowałeś już forum WebSphere? http://ibm.biz/websphere-forum – dbreaux

+0

Nie mogę tego również uruchomić. Kiedy dołączam JacksonJsonProvider do aplikacji getClasses(). Websphere użyje Jacksona. Ale nie ma sposobu, aby dostosować Jackson. Jeśli zamiast tego dołączę niestandardowy skonfigurowany JacksonJsonProvider w aplikacji getSingletons(). Websphere go nie użyje. Obiekty bez odpowiedzi (lub ich ładunki) są serializowane. Metoda REST, która powinna zwrócić treść odpowiedzi, nie zwraca nic. (Życie z TomcatEE jest o wiele łatwiejsze.) – devdanke

Odpowiedz

-1

I USSE Moxy zamiast Jackson był v8.0.0.x.

Aby zastąpić Jackson, wdrożyć moją klasę aplikacji, jak tak:

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

Jednak zauważyłem, że WAS zdaje się ignorować następującą adnotację:

@ApplicationPath("/resources/") 

Tak, mam uciekają do korzystania z 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> 

Chodzi o to, że WAS lub Wink wydaje się ignorować implementację aplikacji przy korzystaniu z adnotacji ApplicationPath, Wink ładuje domyślną klasę aplikacji, która domyślnie używa Jacksona.

I tak, czytałem dokumentację, a nawet oglądałem internetowe filmy IBM, które wspominają, że @ApplicationPath pozwala uniknąć konfiguracji XML, jednak ten problem wydaje się być błędem.

UPDATE:

Alternatywnym rozwiązaniem mogłoby być to, co David Blevins wspomniał w innym SO postu.

Check out the section Using JAX-RS

+0

Spróbuj użyć procesora Jackson JSON z EJB z adnotacją "@Path" i "@WebService". To jest alternatywa wspomniana w sekcji JAX-RS. Może to pozwolić na ominięcie błędnej implementacji Aplikacji JAX-RS przez WAS. –

2

I rozwiązać ten problem właśnie wdrożenie klasę MessageBodyWriter, tak:

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

każdym razem serializacji JSON jest wymagana, ta klasa przychodzi do działania i wreszcie jego metoda writeTo jest wywoływany .

Tutaj SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS jest wyłączony, zgodnie z żądaniem WebSphere.

Powiązane problemy