1. 程式人生 > >spring boot演示處理session

spring boot演示處理session

一、session原理

原理

1. 客戶端請求服務端,服務端發回響應(包含sessionId)給客戶端

【實操】

/**
 * 列印HttpHeaderss
 * @param headers
*/
private void printHeaders(HttpHeaders headers){
    Iterator<Map.Entry<String,List<String>>> iter = headers.entrySet().iterator();
    while(iter.hasNext()){
        Map.Entry<String,List<String>> entry = iter.next();
System.out.println(entry.getKey()+":"+entry.getValue()); } }

列印Response的HttpHeaders,結果:

Set-Cookie:[JSESSIONID=3CF70F4C94F002A3C0F28B351A795250; Max-Age=28800; Expires=Thu, 01-Mar-2018 17:21:03 GMT; Path=/; HttpOnly]
Content-Type:[text/plain;charset=UTF-8]
Content-Length:[6]

結果中JSESSIONID就是sessionId

2. 客戶端在第二次請求中,在Cookie中加入sessionId,傳送給服務端

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
//將登入的Set-Cookie的值寫入Cookie中
headers.set("Cookie",cookie);
cookie中寫入
JSESSIONID=3CF70F4C94F002A3C0F28B351A795250

3. 服務端在第二次請求時,拿到的sessionId就是客戶端傳過來的sessionId

4. 屬性

Max-Age:瀏覽器拿到sessionId後,通過服務端傳過來的Max-Age來指定sessionId存活的描述

timeout:服務端sessionId超時的秒數,超過指定的秒數,則sessionId失效。

二、 構建服務端

建立spring-boot專案,建立AccountController類

package cn.taonc.demo.resttemplatesession.controller;
import cn.taonc.demo.resttemplatesession.model.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@RestController
public class AccountController {

    private Map<String,User> userMap = new HashMap<>();
/**
     * 登入
     * @param request
* @param user
* @return
*/
@PostMapping("/account/login")
    public String login(HttpServletRequest request,User user){
        //request.getSession(true)強制獲取session,否則session有可能為null.
        //request.getSession()在第一個請求返回時,才產生
String sessionId = request.getSession(true).getId();
//驗證使用者名稱和密碼
if("admin".equals(user.getName()) && "admin".equals(user.getPassword())){
            //將使用者存入Map, sessionId為鍵值
userMap.put(sessionId,user);
            return "Succss";
}
        return "Failed";
}

    /**
     * hello
     * @param request
* @return
*/
@GetMapping("/account/hello")
    public String hello(HttpServletRequest request){
        String sessionId = request.getSession(true).getId();
        if(!userMap.containsKey(sessionId)){
            return "請登入";
}else{
            return "歡迎您:"+userMap.get(sessionId).getName() + "!";
}
    }
}

application.properties配置

server.port=8081
server.session.cookie.max-age=28800
server.session.timeout=28800

三、 寫RestTemplate客戶端測試

package cn.taonc.demo.resttemplatesession.controller;
import org.junit.Test;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class AccountControllerTest {

    private RestTemplate restTemplate = new RestTemplate();
/**
     * 沒有session情況下的請求
     */
@Test
public void helloTestNoSession(){
        String url = "http://localhost:8081/account/hello";
String res = restTemplate.getForObject(url,String.class);
System.out.println(res);
}

    /**
     * 有session的情況下的請求
     */
@Test
public void helloTestWithSession(){
        String url = "http://localhost:8081/account/login";
//登入
ResponseEntity<String> loginRes = login(url);
//從登入的結果中提取header:Set-Cookie
String cookie = getCookie(loginRes);
String url2 = "http://localhost:8081/account/hello";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
//將登入的Set-Cookie的值寫入Cookie中
headers.set("Cookie",cookie);
HttpEntity httpEntity = new HttpEntity(null,headers);
ResponseEntity<String> linkListRes = restTemplate.exchange(url2, HttpMethod.GET,httpEntity,String.class);
System.out.println(linkListRes.getBody());
}

    private ResponseEntity<String> login(String url){
        HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("name", "admin");
map.add("password", "admin");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url,request,String.class);
        return responseEntity;
}

    private String getCookie(ResponseEntity responseEntity){
        List<String> cookies = responseEntity.getHeaders().get("Set-Cookie");
System.out.println("Set-Cookie:"+cookies);
       return cookies.get(0);
}
}

測試結果(helloTestNoSession):

請登入

測試結果(helloTestWithSession):

歡迎您:admin!