【问题标题】:Issue injecting @Context in resource class在资源类中注入@C​​ontext 问题
【发布时间】:2015-04-24 11:51:23
【问题描述】:

我在将 HttpHeaders 注入我的休息服务类时遇到了困难。

@Path("/account")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
@Transactional
@Service
public class UserServiceImpl implements UserService {
    @Context
    private HttpHeaders headers;

    @Override
    @POST @Path("/{username}/")
    public User get(@PathParam(value = "username") String username)
        throws UnknownUserException {
        String requestId = headers.getHeaderString("requestId");

        return new User();
    }
}

当我尝试运行应用程序时,我在 spring 初始化期间收到以下异常:

Caused by: java.lang.IllegalArgumentException: Can not set javax.ws.rs.core.HttpHeaders field com.acme.service.UserServiceImpl.headers to com.sun.proxy.$Proxy50
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
        at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
        at java.lang.reflect.Field.set(Field.java:758)
        at org.apache.cxf.jaxrs.utils.InjectionUtils$1.run(InjectionUtils.java:192)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.cxf.jaxrs.utils.InjectionUtils.injectFieldValue(InjectionUtils.java:188)
        at org.apache.cxf.jaxrs.utils.InjectionUtils.injectContextProxiesAndApplication(InjectionUtils.java:1058)
        at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.injectContexts(JAXRSServerFactoryBean.java:405)
        at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.updateClassResourceProviders(JAXRSServerFactoryBean.java:429)
        at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:162)

一些实验表明我在尝试注入任何东西时遇到了同样的错误。我有一个异常映射器,其中注入了 http 标头会出现问题,所以我创建了一个自定义提供程序来获取标头,但在注入时遇到了同样的问题。

我很确定我在这里一定遗漏了一些基本的东西。

我知道我可以从标头中添加我需要的内容作为方法的参数,但我无法更改接口。

为操作添加上下文

    @Override
    @POST @Path("/{username}/")
    public User get(@Context HttpHeaders httpHeaders, @PathParam(value = "username") String username)

给我以下错误。

java.lang.IllegalArgumentException: object is not an instance of declaring class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:181)
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:97)

我发现如果我删除了 implements 接口,那么应用程序实际上会启动,但实际上并没有注入任何东西。

【问题讨论】:

  • 尝试将其注入到方法参数中,看看会发生什么
  • @peeskillet 一个错误:-(我已经更新了我的问题

标签: spring cxf jax-rs


【解决方案1】:

我找到了一种解决方法(或者可能是预期的解决方案)。看来spring正在使用基于接口的代理。我创建了一个中间接口,并在接口上坚持了setHttpHeaders 操作,并用@Context 注释了实现。一切似乎都很好。

public interface MyService {
    void doStuff();
}

public interface MyServiceInt extends MyService  {
    void setHttpHeaders(HttpHeaders headers);
}

@Path("/")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
@Transactional
@Service
public class MyServiceImpl implements MyServiceInt {
    private HttpHeaders httpHeaders;

    @Context
    void setHttpHeaders(HttpHeaders headers) {
        this.httpHeaders = httpHeaders;
    }

    @Override
    @POST @Path("/doStuff")
    public void doStuff() {
    }
}

如果有人知道,仍然希望听到更好的解决方案。

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多