@PathVariable @RequestParam @RequestBody @ModelAttribute的區別及RestTemplate呼叫方式

magicTan發表於2019-04-13

@PathVariable

  • 能匹配url模板中的佔位符對應引數
  • 支援get和post請求
  • Controller宣告:
//get-uri: localhost:8080/test/pathVariable/123
@GetMapping(value = "pathVariable/{param}")
public String getPathVariable(@PathVariable("param") String id) {
    return id;
}

//post-uri: localhost:8080/test/pathVariable/123
@PostMapping(value = "pathVariable/{param}")
public String postPathVariable(@PathVariable("param") String id) {
    return id;
}
複製程式碼
  • RestTemplate訪問:
public static void pathVariable() {
    Map<String, String> map = new HashMap<>();
    map.put("paramName", "name1");
    RestTemplate restTemplate = new RestTemplate();
    //get呼叫使用getForEntity
    ResponseEntity<String> responseEntity = restTemplate.getForEntity(host+"/test/pathVariable/{paramName}", String.class, map);
    //post需要用postForEntity方法呼叫
    //ResponseEntity<String> responseEntity = restTemplate.postForEntity(host+"/test/pathVariable/{paramName}", null, String.class, map);
    System.out.println("getPathVariable2: " + responseEntity.getBody());//輸出“name1”
}
複製程式碼

@RequestParam

  • 與PathVariable類似,RequestParam只能用於url引數傳值,可傳入簡單型別、指定對映引數名、指定是否必填、設定預設值等
  • 支援get和post請求
  • Controller宣告:
//get-uri: localhost:8080/test/requestParam?param=xxx
@GetMapping(value = "test/requestParam")
public String getRequestParam(@RequestParam(defaultValue = "ssss") String param) {
//當請求url為localhost:8080/test/requestParam時,param為預設值ssss
    
//post-uri: localhost:8080/test/requestParam?param=xxx
@PostMapping(value = "test/requestParam")
public String getRequestParam(@RequestParam(name = "aa", required = false) String param) {
//指定引數為“aa”,即當url為localhost:8080/test/requestParam?aa=p1時,param為p1
//當url為localhost:8080/test/requestParam時,param為null

//post-uri: localhost:8080/test/requestParam
@PostMapping(value = "test/requestParam")
public String postRequestParam(@RequestParam(required = false) int param) {
// int是基本型別,即使設定required=false,因為int無法設定為null仍然會報錯,可以將int替換為Integer
複製程式碼
  • RestTemplate訪問:
public static void requestParam() {
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> responseEntity = restTemplate.getForEntity(host+"/test/requestParam",
            String.class);
    System.out.println("getRequestParam: " + responseEntity.getBody());//url未指定,預設值為ssss
    
    Map<String, String> map = new HashMap<>();
    map.put("param", "name3");
    responseEntity = restTemplate.getForEntity(host+"/test/requestParam?param={param}", String.class);
    System.out.println("getRequestParam: " + responseEntity.getBody());//輸出name3
}

public static void requestParam2() {
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<String> responseEntity = restTemplate.postForEntity(host+"/test/requestParam",
            String.class);
    System.out.println("postRequestParam: " + responseEntity.getBody());//未指定aa,輸出結果為null
}
複製程式碼

@RequestBody

  • RequestBody主要通過請求體body傳值,常用來處理content-type=application/json請求,同時支援get和post請求,能獲取到body中的資料並轉化為物件
  • 支援get和post請求
  • Controller宣告:
//get-uri: localhost:8080/test/requestBody
@GetMapping(value = "test/requestBody")
public BaseParam getRequestBody(@RequestBody BaseParam param) {
    return param;
}

//post-uri: localhost:8080/test/requestBody
@PostMapping(value = "test/requestBody")
public BaseParam postRequestBody(@RequestBody BaseParam param) {
    return param;
}
複製程式碼
  • RestTemplate訪問:
//get請求
//RestTemplate的get請求不支援設定body,所以使用restTemplate無法呼叫get請求的@RequestBody註解,但使用PostMan等工具是可以傳送帶body的get請求的

//post請求
public static void postRequestBody() {
    HttpHeaders requestHeaders = new HttpHeaders();
    //注意設定content-type
    requestHeaders.add("Content-type", MediaType.APPLICATION_JSON_VALUE);
    BaseParam param = new BaseParam();
    param.setParamName("name4");
    HttpEntity<BaseParam> requestEntity = new HttpEntity<>(param, requestHeaders);
    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<BaseParam> responseEntity = restTemplate.postForEntity(host+"/test/requestBody",
            requestEntity, BaseParam.class);
    System.out.println("postRequestBody: " + responseEntity.getBody().getParamName());//輸出name4
}

複製程式碼

@ModelAttribute

  • ModelAttribute註解引數時,傳送請求的content-type需要為"x-www-form-urlencoded"
  • 僅支援post請求且content-type=x-www-form-urlencoded能接收到資料;如果是post請求且content-type=application/json、get請求且content-type=x-www-form-urlencoded、get請求且content-type=application/json均不會報錯但無法接收到資料
  • Controller宣告:
@PostMapping(value = "test/modelAttribute")
public String postModelAttribute(@ModelAttribute BaseParam param) {
    return param.getParamName();
}
複製程式碼
  • RestTemplate訪問:
public static void postModelAttribute() {
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.add("Content-type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
    MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
    params.add("account", "使用者名稱");
    params.add("paramName", "123456");
    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, requestHeaders);
    RestTemplate restTemplate = new RestTemplate();
    //需要提供自定義convert
    restTemplate.getMessageConverters().add(new TestMappingJackson2HttpMessageConverter());
    ResponseEntity<String> responseEntity = restTemplate.postForEntity(host+"/test/modelAttribute",
            requestEntity, String.class);
    System.out.println("postModelAttribute: " + responseEntity.getBody());//輸出123456
}
    
//自定義convert
public class TestMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
    public TestMappingJackson2HttpMessageConverter() {
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.TEXT_PLAIN);
        //新增form-urlencoded型別轉換
        mediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        setSupportedMediaTypes(mediaTypes);
    }
}
複製程式碼

以上對@PathVariable、@RequestParam、@RequestBody、@ModelAttribute的使用方式及RestTemplate如何呼叫相應註解介面做了總結,如有不對歡迎指出,謝謝!

相關文章