使用guice,如何配置Jersey的媒体类型映射?

时间:2014-06-04 17:21:55

标签: java jersey guice jersey-1.0

我已经让Guice配置了Jersey,而且它运行得很好。这是我到目前为止所做的事情:

import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletScopes;
import com.company.app.ejb.lookup.EjbProvider;
import com.company.app.rest.exception.ConditionExceptionMapper;
import com.company.app.rest.exception.InvalidSortExceptionMapper;
import com.company.app.rest.exception.NotFoundExceptionMapper;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;

/*
From http://randomizedsort.blogspot.com/2011/05/using-guice-ified-jersey-in-embedded.html
 */
public class GuiceServletConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new JerseyServletModule() {
            @Override
            protected void configureServlets() {
                install(new EjbProvider());
                install(new JacksonJsonProviderProvider());

                // Must configure at least one JAX-RS resource or the
                // server will fail to start.
                bind(RestApiVersion1.class).in(ServletScopes.REQUEST);
                bind(RestApiVersion2.class).in(ServletScopes.REQUEST);

                bind(ConditionExceptionMapper.class).in(Singleton.class);
                bind(InvalidSortExceptionMapper.class).in(Singleton.class);
                bind(NotFoundExceptionMapper.class).in(Singleton.class);

//                bind(ResourceConfigClass.class).in(Singleton.class);  this does not work :(

                // Route all requests through GuiceContainer
                serve("/*").with(GuiceContainer.class, ImmutableMap.of(JSONConfiguration.FEATURE_POJO_MAPPING, "true"));

            }
        });
    }
}

我有这个非常简单的ResourceConfigClass,它看起来像这样:

import com.sun.jersey.api.core.PackagesResourceConfig;

import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.Map;

public class ResourceConfigClass extends PackagesResourceConfig {
    public ResourceConfigClass(String... packages) {    //this constructor needs to be here, do not delete it or else the com.sun.jersey.config.property.packages param can't be passed in.
        super(packages);
    }

    public ResourceConfigClass(Map<String, Object> props) { //this constructor needs to be here, do not delete it or else the com.sun.jersey.config.property.packages param can't be passed in.
        super(props);
    }

    @Override
    public Map<String, MediaType> getMediaTypeMappings() {
        Map<String, MediaType> map = new HashMap<String, MediaType>();
        map.put("xml", MediaType.APPLICATION_XML_TYPE);
        map.put("json", MediaType.APPLICATION_JSON_TYPE);
        return map;
    }
}

但是,我无法弄清楚如何配置Guice来使用我已经制作的ResourceConfigClass。如果我bind,我在启动时会收到此错误:

#|2014-06-04T10:11:03.324-0700|SEVERE|glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=345;_ThreadName=Thread-2;|Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: com.google.inject.CreationException: Guice creation errors:

1) Could not find a suitable constructor in com.company.app.rest.resource.ResourceConfigClass. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
  at com.company.app.rest.resource.ResourceConfigClass.class(ResourceConfigClass.java:13)
  at com.company.app.rest.resource.GuiceServletConfig$1.configureServlets(GuiceServletConfig.java:38)

在我使用Guice之前,我可以通过将它放在我的web.xml中来使用这个类:

    <init-param>
        <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
        <param-value>com.company.app.rest.resource.ResourceConfigClass</param-value>
    </init-param>

但我不知道如何在GuiceServletConfig中设置该属性。当我使用带有guice的泽西时,如何设置媒体类型映射?

1 个答案:

答案 0 :(得分:2)

我能够这样做:

            serve("/*").with(GuiceContainer.class, ImmutableMap.of(
                    JSONConfiguration.FEATURE_POJO_MAPPING, "true",
                    "com.sun.jersey.config.property.packages", "com.fasterxml.jackson.jaxrs.json",
                    "com.sun.jersey.config.property.resourceConfigClass", "com.company.app.rest.resource.ResourceConfigClass"
            ));

但我找到了更直接的方法:

            serve("/*").with(GuiceContainer.class, ImmutableMap.of(
                    JSONConfiguration.FEATURE_POJO_MAPPING, "true",
                    ResourceConfig.PROPERTY_MEDIA_TYPE_MAPPINGS, "xml:" + MediaType.APPLICATION_XML_TYPE + ",json:" + MediaType.APPLICATION_JSON_TYPE
            ));

现在我不需要额外的ResourceConfigClass课程。这种格式记录在com.sun.jersey.api.core.ResourceConfig#PROPERTY_MEDIA_TYPE_MAPPINGS