配置Wildfly 10使用Jackson(作为JSON提供者)

Ali*_*lin 7 rest jax-rs resteasy jackson wildfly

我有一个应用程序,其中包含使用Jersey和Jackson构建的Web服务作为JSON提供程序,所有这些都在Tomcat应用程序服务器中.

我需要让这个应用程序在Wildfly 10上工作,一切都运行正常,除了没有考虑Jackson注释的webservice响应.从我读到的Wildfly使用Jettison作为默认值,在较新版本中使用Jackson2.

首选的解决方案是使RestEasy(来自Wildfly 10)使用Jackson,为此我尝试排除Jackson2和Jettison并在(META-INF\jboss-deployment-structure.xml)中依赖于Jackson,如下所示:

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
    <exclusions>
        <module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
        <module name="org.jboss.resteasy.resteasy-jettison-provider"/>
    </exclusions>
    <dependencies>
        <module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
    </dependencies>
</deployment>
</jboss-deployment-structure>
Run Code Online (Sandbox Code Playgroud)

显然这还不够,因为表现得像以前一样.我还应该尝试什么?

更新:

由于我的应用程序应该在Tomcat(使用Jersey)和Wildfly(使用RestEasy)上工作相同,我不能依赖于在我的应用程序中使用jackte,因此我正在导入org.codehaus.jackson.

所以,我这样注册我的应用程序:

import javax.ws.rs.core.Application;
public class RestApplication extends Application
{
   @Override
   public Set<Class<?>> getClasses() {
       Set<Class<?>> classes = new HashSet<Class<?>>();

       classes.add(RestObjectMapperProvider.class);
       classes.add(GeneratedService.class);

       return classes;
   }
}
Run Code Online (Sandbox Code Playgroud)

和rest对象映射器提供者:

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import org.codehaus.jackson.map.ObjectMapper;
@Provider
public class RestObjectMapperProvider implements ContextResolver<ObjectMapper>
{
   private final ObjectMapper objectMapper;

   public RestObjectMapperProvider()
   {
       this.objectMapper = new ObjectMapper();

       this.objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
   }

   @Override
   public ObjectMapper getContext(Class<?> type)
   {
       return this.objectMapper;
   }
}
Run Code Online (Sandbox Code Playgroud)

我正在用Gradle构建我的应用程序,下面是杰克逊依赖:

compile group: 'org.codehaus.jackson', name: 'jackson-jaxrs', version: '1.9.+'
Run Code Online (Sandbox Code Playgroud)

由于在Tomcat(泽西岛)下考虑了注释,我的猜测是在Wildfly中我的排除不被考虑.除了检查响应之外,有没有办法检查哪个JSON Provider被考虑?

tea*_*ran 5

我很好奇您为什么使用Jackson 1.x而不是2.x?两者的说明相似,但必须更改Jackson配置。以下是1.x的说明。

jboss-deployment-structure.xml(与您的相同):

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
    <exclusions>
        <module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
        <module name="org.jboss.resteasy.resteasy-jettison-provider"/>
    </exclusions>
    <dependencies>
        <module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
    </dependencies>
</deployment>
</jboss-deployment-structure>
Run Code Online (Sandbox Code Playgroud)

使用@Application注册您的应用程序:

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

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<Class<?>>();

        classes.add(JacksonConfigurationProvider.class);
        classes.add(TestResource.class);

        return classes;
    }

}
Run Code Online (Sandbox Code Playgroud)

使用杰克逊配置提供程序,例如:

@Provider
@Consumes({MediaType.APPLICATION_JSON, "text/json"})
@Produces({MediaType.APPLICATION_JSON, "text/json"})
public class JacksonConfigurationProvider extends ResteasyJacksonProvider {

    private static final Logger LOGGER = LoggerFactory.getLogger(JacksonConfigurationProvider.class);

    public JacksonConfigurationProvider() {
        super();

        LOGGER.info("loading jackson configurator");

        JacksonObjectMapper mapper = JacksonObjectMapper.get();
        setMapper(mapper);

    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在您的JacksonObjectMapper中,告诉它读取批注:

public class JacksonObjectMapper extends ObjectMapper {
    public static JacksonObjectMapper get() {
        JacksonObjectMapper mapper = new JacksonObjectMapper();

        mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);

        JacksonAnnotationIntrospector jacksonAnnotationIntrospector = new JacksonAnnotationIntrospector();
        mapper.setDeserializationConfig(mapper.getDeserializationConfig().withAnnotationIntrospector
                (jacksonAnnotationIntrospector));
        mapper.setSerializationConfig(mapper.getSerializationConfig().withAnnotationIntrospector
                (jacksonAnnotationIntrospector));

        return mapper;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的杰克逊物体看起来像这样:

@JsonRootName("foobar")
public class TestType {

    @JsonProperty("goodbye")
    String hello;

    public String getHello() {
        return hello;
    }

    public void setHello(String hello) {
        this.hello = hello;
    }
}
Run Code Online (Sandbox Code Playgroud)

为了方便起见,我的web.xml中也有此代码,它允许您通过将.json放在URL上而不是设置标头来请求json:

<context-param>
    <param-name>resteasy.media.type.mappings</param-name>
    <param-value>json : application/json, xml : application/xml</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

当我致电http://127.0.0.1:8080/api/v1/test.json时,我得到:

{
    "foobar": {
        "goodbye": "Here is some random string"
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经在这里发布了完整的工作代码:https : //github.com/teacurran/java-experiments/tree/master/stackoverflow-sandbox/Q42416036


Ali*_*lin 1

解决方法是将排除项和依赖项放在子部署中,而不是像我所做的那样放在部署标记中。

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<sub-deployment name="axis.war">
    <exclusions>
        <module name="org.jboss.resteasy.resteasy-jackson2-provider"/>
        <module name="org.jboss.resteasy.resteasy-jettison-provider"/>
    </exclusions>
    <dependencies>
        <module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
    </dependencies>
</sub-deployment>
Run Code Online (Sandbox Code Playgroud)