在业务层使用@Context注解访问HttpServletRequest
Access HttpServletRequest using @Context annotaion in business layer
我可以通过在我的休息服务中使用@Context 注释来访问HttpServletRequest。但是无法访问存储库中的相同内容 class.I 不想在调用方法时将请求表单 MyService 传递给 MyRespository。
@Path("/someUrl")
public MyService{
@Context
private HttpServletRequest request;
@Get
public void someMethod()
{
myRepository.someMethod();
}
}
但是相同的注释不适用于我的存储库 class
@Repository
public MyRepository
{
@Context
private HttpServletRequest request;
public void someMethod()
{
//need request here
}
}
它注入空请求。不确定为什么这不起作用。
问题在于 Jersey(以及 its DI 框架 HK2)的集成方式,即 Spring 组件可以注入 Jersey(HK2)组件,但是反之亦然。 HttpServletRequest
绑定为 Jersey 组件。
您可以做的是创建一个 HK2 服务,它包装了 Spring 存储库和 HttpServletRequest
。 IMO,无论如何这是更好的设计。存储库不应该关心 HttpServletRequest
,它只关心数据。
所以你可以
public class MyService {
@Inject // or @Autowired (both work)
private MyRepository repository;
@Context
private HttpServletRequest request;
}
然后用HK2绑定服务
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class AppBinder extends AbstractBinder {
@Override
public void configure() {
bindAsContract(MyService.class).in(RequestScoped.class);
// note, if `MyService` is an interface, and you have
// an implementation, you should use the syntax
//
// bind(MyServiceImpl.class).to(MyService.class).in(...);
//
// Then you inject `MyService`. Whatever the `to(..)` is,
// that is what you can inject
}
}
并向 Jersey 注册活页夹
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new AppBinder());
}
}
然后您可以将 MyService
注入您的资源 class。
如果你不想走这条路,那么你需要制作 MyRepository
一个 HK2 服务,或者使用一个 HK2 Factory
来包装存储库,并明确地注入它。像
import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;
public class MyRepositoryFactory implements Factory<MyRepository> {
private final MyRepository repo;
@Inject
public MyRepositoryFactory(ApplicationContext ctx, ServiceLocator locator) {
MyRepository r = ctx.getBean(MyRepository.class);
locator.inject(r);
this.repo = r;
}
@Override
public MyRepository provide() {
return repo;
}
@Override
public void dispose(MyRepository t) {/* noop */}
}
然后注册工厂
@Override
public void configure() {
bindFactory(MyRepositoryFactory.class).to(MyRepository.class).in(Singleton.class);
}
如果你这样做,那么你只是使用MyRepository
,而不是添加服务层。基本上,您需要从 Spring 获取 repo,并使用 HK2 ServiceLocator
(这是 Spring ApplicationContext
的 HK2 类似物)显式注入它。
我可以通过在我的休息服务中使用@Context 注释来访问HttpServletRequest。但是无法访问存储库中的相同内容 class.I 不想在调用方法时将请求表单 MyService 传递给 MyRespository。
@Path("/someUrl")
public MyService{
@Context
private HttpServletRequest request;
@Get
public void someMethod()
{
myRepository.someMethod();
}
}
但是相同的注释不适用于我的存储库 class
@Repository
public MyRepository
{
@Context
private HttpServletRequest request;
public void someMethod()
{
//need request here
}
}
它注入空请求。不确定为什么这不起作用。
问题在于 Jersey(以及 its DI 框架 HK2)的集成方式,即 Spring 组件可以注入 Jersey(HK2)组件,但是反之亦然。 HttpServletRequest
绑定为 Jersey 组件。
您可以做的是创建一个 HK2 服务,它包装了 Spring 存储库和 HttpServletRequest
。 IMO,无论如何这是更好的设计。存储库不应该关心 HttpServletRequest
,它只关心数据。
所以你可以
public class MyService {
@Inject // or @Autowired (both work)
private MyRepository repository;
@Context
private HttpServletRequest request;
}
然后用HK2绑定服务
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class AppBinder extends AbstractBinder {
@Override
public void configure() {
bindAsContract(MyService.class).in(RequestScoped.class);
// note, if `MyService` is an interface, and you have
// an implementation, you should use the syntax
//
// bind(MyServiceImpl.class).to(MyService.class).in(...);
//
// Then you inject `MyService`. Whatever the `to(..)` is,
// that is what you can inject
}
}
并向 Jersey 注册活页夹
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new AppBinder());
}
}
然后您可以将 MyService
注入您的资源 class。
如果你不想走这条路,那么你需要制作 MyRepository
一个 HK2 服务,或者使用一个 HK2 Factory
来包装存储库,并明确地注入它。像
import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;
public class MyRepositoryFactory implements Factory<MyRepository> {
private final MyRepository repo;
@Inject
public MyRepositoryFactory(ApplicationContext ctx, ServiceLocator locator) {
MyRepository r = ctx.getBean(MyRepository.class);
locator.inject(r);
this.repo = r;
}
@Override
public MyRepository provide() {
return repo;
}
@Override
public void dispose(MyRepository t) {/* noop */}
}
然后注册工厂
@Override
public void configure() {
bindFactory(MyRepositoryFactory.class).to(MyRepository.class).in(Singleton.class);
}
如果你这样做,那么你只是使用MyRepository
,而不是添加服务层。基本上,您需要从 Spring 获取 repo,并使用 HK2 ServiceLocator
(这是 Spring ApplicationContext
的 HK2 类似物)显式注入它。