Сървлетът HttpSession
е в JSR-356, достъпен от HandshakeRequest#getHttpSession()
, което от своя страна е достъпно, когато се направи заявка за ръкостискане точно преди @OnOpen
от @ServerEndpoint
. ServletContext
от своя страна е достъпен само чрез HttpSession#getServletContext()
. Това са два заека с един камък.
За да заснемете заявката за ръкостискане, имплементирайте ServerEndpointConfig.Configurator
и замени modifyHandshake()
метод. HandshakeRequest
тук е наличен като аргумент на метода. Можете да поставите HttpSession
в EndpointConfig#getUserProperties()
a>. EndpointConfig
от своя страна е наличен като аргумент на метод @OnOpen
.
Ето начален пример за внедряване на ServerEndpointConfig.Configurator
:
public class ServletAwareConfig extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
config.getUserProperties().put("httpSession", httpSession);
}
}
Ето как можете да го използвате, обърнете внимание на configurator
атрибут на @ServerEndpoint
:
@ServerEndpoint(value="/your_socket", configurator=ServletAwareConfig.class)
public class YourSocket {
private EndpointConfig config;
@OnOpen
public void onOpen(Session websocketSession, EndpointConfig config) {
this.config = config;
}
@OnMessage
public void onMessage(String message) {
HttpSession httpSession = (HttpSession) config.getUserProperties().get("httpSession");
ServletContext servletContext = httpSession.getServletContext();
// ...
}
}
Като намек за дизайн, най-добре е да запазите своя @ServerEndpoint
напълно свободен от зависимости на API на сървлета. Бихте могли в modifyHandshake()
изпълнението по-добре веднага да извлечете точно тази информация (обикновено променлив Javabean), от която се нуждаете от сесията на сървлета или контекста, и вместо това да ги поставите в картата на потребителските свойства. Ако не направите това, тогава трябва да имате предвид, че една websocket сесия може да живее по-дълго от HTTP сесията. Така че, когато все още носите около HttpSession
в крайната точка, тогава може да се натъкнете на IllegalStateException
, когато се опитате да получите достъп до него, докато е изтекъл.
В случай, че случайно имате CDI (и може би JSF) под ръка, може да почерпите вдъхновение от изходния код на OmniFaces <o:socket>
(връзките са в най-долната част на витрината).
Вижте също:
person
BalusC
schedule
01.05.2014
configurator = org.springframework.web.socket.server.endpoint.SpringConfigurator.class
във вашата@ServerEndpoint
анотация. - person Peter G   schedule 03.05.2014