Есть хороший пример совместного использования HttpSession между Websocket и сервисом Rest. (Spring DispatchServlet не может найти ресурс в Jetty) Но это не так. работай на меня. Я не уверен, есть ли что-то, что мне не хватает?
Я использую Jetty в качестве сервера веб-сокетов, а также создал WebApp, который вводится SpringConfig.
private void init() throws Exception
{
Server server = new Server();
// Create SSL Connector
ServerConnector serverConnector = getSSLConnector(server);
// Bundle to server
server.setConnectors(new Connector[] { serverConnector });
// Create request handler collection
HandlerCollection handlers = new HandlerCollection();
// Add WebSocket handler
final ServletContextHandler servletContextHandler = getWebSocketContextHandler();
handlers.addHandler(servletContextHandler);
// Add Servlet handler
handlers.addHandler(getWebAppServletContextHandler());
server.setHandler(handlers);
// Initial WebSocket
WebSocketServerContainerInitializer.configureContext(servletContextHandler);
// Start Jetty
server.start();
server.join();
}
И WebSocket, и Rest отлично работают с одним и тем же портом, конечно, с разными путями контекста.
Теперь я создал службу Rest:
@RequestMapping(value = "/login", method = RequestMethod.POST)
@Consumes({ MediaType.APPLICATION_JSON_VALUE })
@Produces({ MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody Message login(@RequestBody Credential credential, @Context HttpServletRequest servlerRequest)
{
...
HttpSession session = servlerRequest.getSession(true);
session.setAttribute("userName", credential.getUserName());
...
Message message = new Message();
...
return message;
}
В этом сервисе я создал HttpSession и что-то сохранил. Как я уже сказал, он работает, и сеанс тоже.
Отдых клиент:
public void login() throws KeyManagementException, NoSuchAlgorithmException
{
final String loginServiceUri = HTTP_SERVICE_BASE_URI + "/login";
ClientConfig clientConfig = new DefaultClientConfig();
...
Client client = Client.create(clientConfig);
WebResource webResource = client.resource(loginServiceUri);
ClientResponse response = webResource
.type("application/json")
.post(ClientResponse.class, new Credential("user","pass"));
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
List<NewCookie>cookies = response.getCookies();
ClientEndpointConfigurator.setCookies(cookies); <== Store cookies as well as session to ClientEndpointConfigrator class
Message message = response.getEntity(Message.class);
...
}
Класс ClientEndpointConfigrator имеет статический список для всех файлов cookie, которые похожи на это:
public class ClientEndpointConfigurator extends ClientEndpointConfig.Configurator {
private static List<NewCookie> cookies = null;
public static void setCookies(List<NewCookie> cookies) {
ClientEndpointConfigurator.cookies = cookies;
}
...
@Override
public void beforeRequest(Map<String, List<String>> headers) {
...
if(null != cookies)
{
List<String> cookieList = new ArrayList<String>();
for(NewCookie cookie: cookies)
{
cookieList.add(cookie.toString());
}
headers.put("Cookie", cookieList);
}
...
}
}
Метод beforeRequest() поместит все файлы cookie в заголовок запроса. Если вы проверите cookieList, вы увидите:
[JSESSIONID=tvum36z6j2bc1p9uf2gumxguh;Версия=1;Путь=/rs;Безопасный]
Вещи выглядят идеально.
Наконец, создайте серверный класс ServerEndpointConfigurator и переопределите методmodifyHandshake() для получения сеанса и файлов cookie.
public class SpringServerEndpointConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
super.modifyHandshake(sec, request, response);
httpSession = (HttpSession)request.getHttpSession(); <== **It returns null here!**
...
}
}
}
Я не могу вернуть свой HttpSession! и если вы распечатаете заголовки, вы увидите, что файл cookie был изменен:
Файл cookie: JSESSIONID="tvum36z6j2bc1p9uf2gumxguh";$Path="/rs"
Кто-нибудь знает, в чем причина?