Только и только если ваш POJO работает в том же потоке , в котором работает HttpServletRequest
, вы сможете достичь этого с помощью ThreadLocal<T>
.
Создайте следующий класс:
public final class YourContext implements AutoCloseable {
private static ThreadLocal<YourContext> instance = new ThreadLocal<>();
private HttpServletRequest request;
private HttpServletResponse response;
private YourContext(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
public static YourContext create(HttpServletRequest request, HttpServletResponse response) {
YourContext context = new YourContext(request, response);
instance.set(context);
return context;
}
public static YourContext getCurrentInstance() {
return instance.get();
}
@Override
public void close() {
instance.remove();
}
public HttpServletRequest getRequest() {
return request;
}
public HttpSession getSession() {
return request.getSession();
}
public ServletContext getServletContext() {
return request.getServletContext();
}
// ... (add if necessary more methods here which return/delegate the request/response).
}
Реализуйте javax.servlet.Filter
, который выполняет следующие действия в методе doFilter()
и отображается на интересующий url-pattern
, например, /*
или servlet-name
вашего сервлета фронт-контроллера.
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try (YourContext context = YourContext.create(request, response)) {
chain.doFilter(request, response);
}
}
Обратите внимание на важность оператора try-with-resources. Это гарантирует, что YourContext#close()
будет вызван после того, как фильтр выполнит свою работу, а ресурс ThreadLocal
будет очищен. В противном случае поток все равно будет содержать его при повторном использовании для другого HTTP-запроса.
А вот как вы могли бы использовать его в POJO:
YourContext context = YourContext.getCurrentInstance();
HttpSession session = context.getSession();
В основном все это также работает с Context
объектами среднего MVC-фреймворка, такими как FacesContext
JSF и объект в Wicket.
Сказал, что вы смотрели на CDI ? Возможно, проще создать артефакты, управляемые CDI, чтобы вы могли просто @Inject
соединить их друг с другом.