2014-05-05 4 views
6

Wir verwenden IBM (s) bündelt Apache Wink, um JAXRS-Endpunkte für unsere Anwendung anzubieten. Wir codieren Websphere 8.5.5. Da wir Servlet 3.0-kompatibel sind, verwenden wir die "programmatische" Art der Konfiguration der JaxRS-Anwendung, dh keine Einträge in web.xml, und wir verlassen uns auf Klassenscan für annotierte jax rs-Ressourcen. Im Allgemeinen funktioniert es gut.Überschreiben Jackson Object Mapper-Eigenschaften auf Websphere 8.5.5 mit Apache Wink

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

Diese Version von Websphere zusammen mit Apache Wink verwendet Jackson 1.6.x für JSON de/Serialisierung und es funktioniert gut im Allgemeinen. Wir möchten jedoch einige der Standardwerte des Object Mappers ändern.

Also haben wir einen Customer Context Resolver definiert, wo nur einige der se/deserialzation Eigenschaften geändert werden.

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

Während JAX-RS Anrufe können wir sehen, dass der Behälter die neuen Provider registriert, ohne Fehler

Das Problem ist, dass die Konfiguration nicht ‚gefolgt‘, aus den Protokollen kann ich sehen, dass Die Wink-Engine sucht nach einem WinkJacksonProvider, der wiederum einen JacksonProvider zurückgibt, der die Jackson-Standardwerte einhält.

Gibt es eine Möglichkeit, nur diesen Standardwert zu ändern?

Ich habe versucht, die Implementierung des Application-Objekts wie hier angegeben zu ändern, um Provider programmgesteuert zu konfigurieren, aber es hat nicht funktioniert.

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

Irgendwelche Hinweise oder Tipps?

Vielen Dank

+0

Haben Sie das WebSphere-Forum ausprobiert? http://ibm.biz/websphere-forum – dbreaux

+0

Ich kann das auch nicht zur Arbeit bringen. Wenn ich einen JacksonJsonProvider in die Anwendung getClasses() einschließe. Websphere wird Jackson benutzen. Aber es gibt keine Möglichkeit, Jackson anzupassen. Wenn ich stattdessen einen benutzerdefinierten konfigurierten JacksonJsonProvider in der Anwendung getSingletons() einschließe. Websphere wird es nicht verwenden. No Response-Objekte (oder ihre Nutzdaten) werden serialisiert. Die REST-Methode, die einen Antworttext zurückgeben soll, gibt nichts zurück. (Das Leben ist mit TomcateE so viel einfacher.) – devdanke

Antwort

-1

I Usse moxy statt Jackson in WAS v8.0.0.x.

Um Jackson außer Kraft setzen, ich als so meine Application-Klasse implementieren:

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

Allerdings habe ich bemerkt, dass scheint folgende Anmerkung zu ignorieren WAS:

@ApplicationPath("/resources/") 

Also habe ich Zuflucht zur Verwendung von 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> 

Der Punkt ist, seit WS oder Wink scheint die Anwendung zu ignorieren Bei Verwendung der Annotation ApplicationPath lädt Wink die Standardklasse Application, die standardmäßig Jackson verwendet.

Und ja, ich habe Dokumentation gelesen und sogar IBM Videos online gesehen, die erwähnen, dass @ApplicationPath Sie XML Config zu vermeiden ermöglicht, jedoch scheint dieses Problem ein Fehler zu sein.

UPDATE:

Ein alternativer Ansatz könnte sein, was David Blevins in einem anderen SO Beitrag erwähnt hat.

Check out the section Using JAX-RS

+0

Verwenden Sie den Jackson JSON-Prozessor mit einem EJB, der mit "@Path" und "@WebService" versehen ist. Das ist die Alternative, die in der JAX-RS-Sektion erwähnt wird. Dadurch können Sie möglicherweise die fehlerhafte JAX-RS-Anwendungsimplementierung von WAS umgehen. –

2

ich dieses Problem gelöst, indem nur eine MessageBodyWriter Klasse, wie diese Umsetzung:

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

Jedes Mal, wenn eine JSON Serialisierung angefordert wird, kommt diese Klasse in der Tat umzusetzen und schließlich seine WriteTo Methode aufgerufen .

Hier ist SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS deaktiviert, wie von WebSphere angefordert.

Verwandte Themen