在Java web应用, Session 会话保持是依靠浏览器传入一个name为SESSON的cookie而实现的, 默认情况下, spring session 也是采用基于这种方式实现的, spring session会解析请求对象中的cookie. 而Restful风格的API, 倡导的时无状态的请求, 也就是说没有会话保持这个概念的, 即没有session的概念. 通常会采取每个请求都传递一个token 来实现认证参数的传递. spring session对Restful 风格的API 也提供了支持, 可以将Token 存入request Header 中
Set-Cookie:SESSION=M2ZlNzA3YjItNmQzZi00YjkzLThmNjItYTI3MzY5ODQzYzJl; Path=/; HttpOnly; SameSite=Lax
Content-Type:text/plain;charset=UTF-8
Content-Length:66
Date:Wed, 17 Apr 2019 06:10:34 GMT
X-Auth-Token:b9088e9e-3547-48d2-b60a-245835e5c198
Content-Type:text/plain;charset=UTF-8
Content-Length:66
Date:Wed, 17 Apr 2019 05:52:22 GMT
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
@RestController
@RequestMapping("/rest/hello")
public class RestHelloController {
@GetMapping("/say.json")
public String say() {
String result = "sessionId:" + session.getId() + "\n session.isNew:" + session.isNew();
return result;
}
}
由于浏览器中直接输入网址方式没有办法设置请求头携带x-Auth-Token, 所以笔者使用HttpClient 来进行接口调用
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
public class TestHttpUtilRestuful {
String url = "http://localhost:8180/rest/hello/say.json";
// 请求参数不携带x-Auth-Token, 每次获取的都是新的token
@Test
public void test(){
HttpGet httpGet = new HttpGet(url);
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
CloseableHttpResponse response = httpClient.execute(httpGet);
System.out.println("\n******************** 响应 ********************");
String result = EntityUtils.toString(response.getEntity());
System.out.println("response:" + result);
// 返回header 信息
for (Header header : response.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 请求参数携带接口返回的x-Auth-Token, 则返回session 为已存在token
@Test
public void test_with_header(){
// 使用token 测试
String xAuthToken = "d075cdbd-87d4-46b8-b52f-a89b86edd25a2";
HttpGet httpGet = new HttpGet(url);
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
httpGet.setHeader("X-Auth-Token", xAuthToken);
CloseableHttpResponse response = httpClient.execute(httpGet);
System.out.println("\n******************** 响应 ********************");
String result = EntityUtils.toString(response.getEntity());
System.out.println("response:" + result);
// 返回header 信息
for (Header header : response.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
response:sessionId:b9088e9e-3547-48d2-b60a-245835e5c198
session.isNew:true
X-Auth-Token:b9088e9e-3547-48d2-b60a-245835e5c198
Content-Type:text/plain;charset=UTF-8
Content-Length:66
Date:Wed, 17 Apr 2019 05:52:22 GMT
response:sessionId:b9088e9e-3547-48d2-b60a-245835e5c198
session.isNew:false
Content-Type:text/plain;charset=UTF-8
Content-Length:67
Date:Wed, 17 Apr 2019 05:52:58 GMT