簡體   English   中英

在業務層中使用@Context注釋訪問HttpServletRequest

[英]Access HttpServletRequest using @Context annotaion in business layer

我可以在我的rest服務中使用@Context注釋來訪問HttpServletRequest。 但是無法訪問存儲庫類中的相同對象。我不想在調用方法時將請求形式MyService傳遞給MyRespository。

@Path("/someUrl")
public MyService{

@Context
private HttpServletRequest request;

@Get
public void someMethod()
{
   myRepository.someMethod();
}

}

但是相同的注釋不適用於我的存儲庫類

@Repository
public MyRepository
{

@Context
private HttpServletRequest request;

public void someMethod()
{
 //need request here
}
}

它注入空請求。 不知道為什么這不起作用。

問題在於Jersey( 及其 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
    }
}

並在澤西島注冊活頁夾

public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(new AppBinder());
    }
}

然后,您可以將MyService注入資源類。

如果您不想走這條路,則需要將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獲取存儲庫,並顯式地將其注入HK2 ServiceLocator (它是Spring ApplicationContext的HK2類似物)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM