2012-10-23 150 views
0

我想从客户端的角度来看Guice注入与Jersey MessageBodyReader/MessageBodyWriter一起工作。我有服务器与Guice正确启动。我的问题是与客户。Guice Jersey ClientConfig MessageBodyWriters和注入

我鞭打在一起,这表明了错误的情况如下:SEVERE: Missing dependency for constructor public FooExample$FooReader(FooExample$FooUnmarshaller) at parameter index 0

import java.io.IOException; 
import java.io.InputStream; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 

import javax.inject.Inject; 
import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.core.UriBuilder; 
import javax.ws.rs.ext.MessageBodyReader; 

import com.google.inject.AbstractModule; 
import com.google.inject.Guice; 
import com.google.inject.Injector; 
import com.google.inject.Provides; 
import com.sun.jersey.api.client.Client; 
import com.sun.jersey.api.client.WebResource; 
import com.sun.jersey.api.client.config.ClientConfig; 
import com.sun.jersey.api.client.config.DefaultClientConfig; 

class FooExample { 
    public static void main(String[] args) { 
    Injector i = Guice.createInjector(new FooExample().new FooModule()); 
    WebResource service = i.getInstance(WebResource.class); 

    service.path("bar") 
     .accept(MediaType.APPLICATION_XML) 
     .put(String.class, "test123"); 
    } 

    public class FooModule extends AbstractModule{ 
    @Override 
    protected void configure() { 
     bind(FooUnmarshaller.class).to(SimpleFooUnmarshaller.class); 
    } 

    @Provides 
    public WebResource configuredClient() { 
     ClientConfig config = new DefaultClientConfig(); 
     config.getClasses().add(FooReader.class); 
     return Client.create(config).resource(
      UriBuilder.fromUri("http://localhost:8080/foo").build()); 
    } 
    } 

    public static class Foo {} 

    public static interface FooUnmarshaller { 
    public Foo unmarshall(InputStream is); 
    } 

    public static class SimpleFooUnmarshaller implements FooUnmarshaller { 
    @Override 
    public Foo unmarshall(InputStream is) { 
     return new Foo(); 
    } 
    } 

    public static class FooReader implements MessageBodyReader<Foo> { 
    private final FooUnmarshaller marshaller; 

    @Inject 
    public FooReader(FooUnmarshaller marshaller) { 
     this.marshaller = marshaller; 
    } 

    @Override 
    public boolean isReadable(
     Class<?> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType) { 
     return true; 
    } 

    @Override 
    public Foo readFrom(
     Class<Foo> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType, 
     MultivaluedMap<String, String> httpHeaders, 
     InputStream entityStream) throws IOException, WebApplicationException { 
     return marshaller.unmarshall(entityStream); 
    } 
    } 
} 

我在哪里得到的控制台输出:

Oct 23, 2012 3:17:22 PM com.sun.jersey.spi.inject.Errors processErrorMessages 
SEVERE: The following errors and warnings have been detected with resource and/or provider classes: 
    SEVERE: Missing dependency for constructor public FooExample$FooReader(FooExample$FooUnmarshaller) at parameter index 0 
Exception in thread "main" com.google.inject.ProvisionException: Guice provision errors: 

1) Error in custom provider, com.sun.jersey.spi.inject.Errors$ErrorMessagesException 
    at FooExample$FooModule.configuredClient(FooExample.java:40) 
    while locating com.sun.jersey.api.client.WebResource 

1 error 
    at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:987) 
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1013) 
    at FooExample.main(FooExample.java:25) 
Caused by: com.sun.jersey.spi.inject.Errors$ErrorMessagesException 
    at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170) 
    at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136) 
    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199) 
    at com.sun.jersey.api.client.Client.<init>(Client.java:187) 
    at com.sun.jersey.api.client.Client.<init>(Client.java:170) 
    at com.sun.jersey.api.client.Client.create(Client.java:679) 
    at FooExample$FooModule.configuredClient(FooExample.java:42) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at com.google.inject.internal.ProviderMethod.get(ProviderMethod.java:104) 
    at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40) 
    at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:978) 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1024) 
    at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:974) 
    ... 2 more 

我有我需要使用GuiceComponentProviderFactory的感觉,但我似乎无法请在ClientConfig上查找任何文档,也不要使用IoCComponentProviderFactory。任何帮助将非常感激。谢谢!

回答

1

所以我通过猜测和检查来解决我自己的问题。我无法确认这是做事情的有效方式,但这是有效的。

Client类有一个方法:public static Client create(ClientConfig cc, IoCComponentProviderFactory provider),我通过了一个GuiceComponentProviderFactory和事情的成果。上面的代码的工作版本是:

import java.io.IOException; 
import java.io.InputStream; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 

import javax.inject.Inject; 
import javax.ws.rs.WebApplicationException; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.core.UriBuilder; 
import javax.ws.rs.ext.MessageBodyReader; 

import com.google.inject.AbstractModule; 
import com.google.inject.Guice; 
import com.sun.jersey.api.client.Client; 
import com.sun.jersey.api.client.WebResource; 
import com.sun.jersey.api.client.config.DefaultClientConfig; 
import com.sun.jersey.api.core.DefaultResourceConfig; 
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory; 
import com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory; 

class FooExample { 
    public static void main(String[] args) { 
    WebResource service = configuredClient(); 

    service.path("bar") 
     .accept(MediaType.APPLICATION_XML) 
     .put(String.class, "test123"); 
    } 

    private static WebResource configuredClient() { 
    DefaultClientConfig config = new DefaultClientConfig(); 
    config.getClasses().add(FooReader.class); 
    return Client.create(config, provider()).resource(
     UriBuilder.fromUri("http://localhost:8080/foo").build()); 
    } 

    private static IoCComponentProviderFactory provider() { 
    return new GuiceComponentProviderFactory(
     new DefaultResourceConfig(), 
     Guice.createInjector(new FooExample().new FooModule())); 
    } 

    public class FooModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(FooUnmarshaller.class).to(SimpleFooUnmarshaller.class); 
    } 
    } 

    public static class Foo {} 

    public static interface FooUnmarshaller { 
    public Foo unmarshall(InputStream is); 
    } 

    public static class SimpleFooUnmarshaller implements FooUnmarshaller { 
    @Override 
    public Foo unmarshall(InputStream is) { 
     return new Foo(); 
    } 
    } 

    public static class FooReader implements MessageBodyReader<Foo> { 
    private final FooUnmarshaller marshaller; 

    @Inject 
    public FooReader(FooUnmarshaller marshaller) { 
     this.marshaller = marshaller; 
    } 

    @Override 
    public boolean isReadable(
     Class<?> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType) { 
     return true; 
    } 

    @Override 
    public Foo readFrom(
     Class<Foo> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType, 
     MultivaluedMap<String, String> httpHeaders, 
     InputStream entityStream) throws IOException, WebApplicationException { 
     return marshaller.unmarshall(entityStream); 
    } 
    } 
} 

和输出

Oct 23, 2012 5:17:11 PM com.sun.jersey.guice.spi.container.GuiceComponentProviderFactory getComponentProvider 
INFO: Binding FooExample$FooReader to GuiceInstantiatedComponentProvider 
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: PUT http://localhost:8080/foo/bar returned a response status of 404 Not Found 
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686) 
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) 
    at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:537) 
    at FooExample.main(FooExample.java:28) 

意味着吉斯绑定工作! =)