通过 Spring RestTemplate 向客户端执行后续请求时会话关闭错误
Session closed error when performing subsequence requests to client via Spring RestTemplate
我正在尝试使用 spring 休息模板来执行 post 登录请求。
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("LoginForm_Login", "login");
mvm.add("LoginForm_Password", "password");
ResponseEntity<String> result = restTemplate.exchange(uriDWLogin, HttpMethod.POST, requestEntity, String.class);
一切顺利,但是当我尝试发送第二个请求时,它会生成一条错误消息:
Business Manager closes your session after 15 minutes
我该怎么做才能解决这个问题?!
当您在第一个请求中收到响应时,您应该存储通过 cookie 收到的 session id
。您将在 set-cookie
响应 header 中检索它,您可以通过以下方式获取它:
//first request
RestTemplate template = new RestTemplate();
ResponseEntity<String> forEntity = template.getForEntity("http://google.bg", String.class);
forEntity.getHeaders().get("Set-Cookie").stream().forEach(System.out::println);
然后在每个后续请求中,您应该使用第一个请求中收到的值设置 Cookie
请求 header:
//subsequent request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Cookie",cookies.stream().collect(Collectors.joining(";")));
HttpEntity<String> entity = new HttpEntity<String>(headers);
restTemplate.exchange("http://url", HttpMethod.POST, entity, String.class);
我有一个 StaticRestTemplate class,这样我就得到了相同的 RestTemplate 实例。
public class StaticRestTemplate {
public volatile static RestTemplate rest = new RestTemplate();
public static volatile String jsessionid = "";
// This way, I can test on local or server just by changing one URL.
public static volatile String baseURL = "http://192.168.178.60:8080/";
}
登录码:
public static RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
StaticRestTemplate.jsessionid = rest.execute(StaticRestTemplate.baseURL+"j_spring_security_check", HttpMethod.POST,
new RequestCallback() {
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getBody().write(("j_username=" + email + "&j_password=" + password).getBytes());
}
}, new ResponseExtractor<String>() {
@Override
public String extractData(ClientHttpResponse response) throws IOException {
List<String> cookies = response.getHeaders().get("Cookie");
if (cookies == null) {
cookies = response.getHeaders().get("Set-Cookie");
}
String cookie = cookies.get(cookies.size() - 1);
int start = cookie.indexOf('=');
int end = cookie.indexOf(';');
return cookie.substring(start + 1, end);
}
});
return null;
}
现在,我的JsessionID就保存下来了,以后的请求我可以这样直接使用:
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
// This is where I add the cookie value
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
HttpEntity<String> rssResponse = rest.exchange(
StaticRestTemplate.baseURL+"dashboard",
HttpMethod.GET,
requestEntity,
String.class);
StaticRestTemplate.replyString = rssResponse.getBody();
return StaticRestTemplate.replyString;
如有疑问,请告诉我。
您可以尝试为您的 RestTemplate 禁用工厂的 cookie 管理:
HttpClient httpClient = HttpClientBuilder.create()
.disableCookieManagement()
.useSystemProperties()
.build();
factory.setHttpClient(httpClient);
我正在尝试使用 spring 休息模板来执行 post 登录请求。
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
LinkedMultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("LoginForm_Login", "login");
mvm.add("LoginForm_Password", "password");
ResponseEntity<String> result = restTemplate.exchange(uriDWLogin, HttpMethod.POST, requestEntity, String.class);
一切顺利,但是当我尝试发送第二个请求时,它会生成一条错误消息:
Business Manager closes your session after 15 minutes
我该怎么做才能解决这个问题?!
当您在第一个请求中收到响应时,您应该存储通过 cookie 收到的 session id
。您将在 set-cookie
响应 header 中检索它,您可以通过以下方式获取它:
//first request
RestTemplate template = new RestTemplate();
ResponseEntity<String> forEntity = template.getForEntity("http://google.bg", String.class);
forEntity.getHeaders().get("Set-Cookie").stream().forEach(System.out::println);
然后在每个后续请求中,您应该使用第一个请求中收到的值设置 Cookie
请求 header:
//subsequent request
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Cookie",cookies.stream().collect(Collectors.joining(";")));
HttpEntity<String> entity = new HttpEntity<String>(headers);
restTemplate.exchange("http://url", HttpMethod.POST, entity, String.class);
我有一个 StaticRestTemplate class,这样我就得到了相同的 RestTemplate 实例。
public class StaticRestTemplate {
public volatile static RestTemplate rest = new RestTemplate();
public static volatile String jsessionid = "";
// This way, I can test on local or server just by changing one URL.
public static volatile String baseURL = "http://192.168.178.60:8080/";
}
登录码:
public static RestTemplate rest = new RestTemplate();
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
StaticRestTemplate.jsessionid = rest.execute(StaticRestTemplate.baseURL+"j_spring_security_check", HttpMethod.POST,
new RequestCallback() {
@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
request.getBody().write(("j_username=" + email + "&j_password=" + password).getBytes());
}
}, new ResponseExtractor<String>() {
@Override
public String extractData(ClientHttpResponse response) throws IOException {
List<String> cookies = response.getHeaders().get("Cookie");
if (cookies == null) {
cookies = response.getHeaders().get("Set-Cookie");
}
String cookie = cookies.get(cookies.size() - 1);
int start = cookie.indexOf('=');
int end = cookie.indexOf(';');
return cookie.substring(start + 1, end);
}
});
return null;
}
现在,我的JsessionID就保存下来了,以后的请求我可以这样直接使用:
rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
// This is where I add the cookie value
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);
HttpEntity<String> rssResponse = rest.exchange(
StaticRestTemplate.baseURL+"dashboard",
HttpMethod.GET,
requestEntity,
String.class);
StaticRestTemplate.replyString = rssResponse.getBody();
return StaticRestTemplate.replyString;
如有疑问,请告诉我。
您可以尝试为您的 RestTemplate 禁用工厂的 cookie 管理:
HttpClient httpClient = HttpClientBuilder.create()
.disableCookieManagement()
.useSystemProperties()
.build();
factory.setHttpClient(httpClient);