REST理論基礎
REST用不同狀態來進行rpc傳輸,比較輕量級的web服務
架構屬性:
- 性能
- 可伸縮性
- 統一接口簡化性
- 組件可修改性
- 組件通訊可見性
- 組件可移植性
- 可靠性
SpringBoot REST
核心接口:
定義相關:定義是一個Rest接口
- @Controller
- @RestController:是Controller+RestBody的組合
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
映射相關:和URL映射有關
- @RequestMapping
- @GetMapping 4.3版本RequestMapping的替代物
- @PostMapping
- @PathVariable:路徑的變量(動態的)
http://localhost:8080/html/demo3
http://localhost:8080/html/demo/messageString
@RestController
public class RestDemoController {
//HTML
//@RequestMapping(value = {"/html/demo","/html/demo2"},method = {RequestMethod.GET,RequestMethod.POST})
//@GetMapping(path = "/html/demo3")
@PostMapping(path = "/html/demo4")
@ResponseBody
public String htmlCode(){
return "<html><body>hello,world</body></html>";
}
@GetMapping(path = "/html/demo/{message}")
public String htmlPathVariable(@PathVariable String message){
return "<html><body>hello,"+message+"</body></html>";
}
請求相關:
- @RequestParam:看着使用此註解和使用HttpServletRequest去獲取參數都一樣的效果,實際不然,用註解的方式會自動幫你強制轉換成你想要的類型
http://localhost:8080/html/demo/param?p=123
@RestController
public class RestDemoController {
@GetMapping(path = "/html/demo/param")
public String htmlParam(@RequestParam(value = "p",required = false,defaultValue = "1") String param,
HttpServletRequest request){
String param2 = request.getParameter("param2");
return "<html><body>RequestParam value :"+param+",param2 value:"+param2+"</body></html>";
}
}
- @RequestHeader
@RestController
public class RestDemoController {
@GetMapping(path = "/html/demo/header")
public String htmlHeader(@RequestHeader(value = "Accept") String acceptHeader){
return "<html><body>Request Accept value :"+acceptHeader+"</body></html>";
}
}
- @CookieValue
- RequestEntity
響應相關:
- @ResponseBody:響應體 在application.properties配置如下,當只有Controller的時候他會當做一個模板的路徑而不是響應體進行返回,
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp
- ResponseEntity:他跟ResponseBody不同在於他可以存入相應頭和響應體
@GetMapping(path = "/html/demo/response/entity")
public ResponseEntity<String> htmlResponseEntity() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.put("MyHeader", Arrays.asList("MyHeaderValue"));
ResponseEntity responseEntity = new ResponseEntity("<html><body>HTML ResponseEntity </body></html>", httpHeaders, HttpStatus.OK);
return responseEntity;
}
對於映射相關的 不可以同時存在不會同時生效只會生效最上面的那一個
@RequestMapping(value = {"/html/demo","/html/demo2"},method = {RequestMethod.GET,RequestMethod.POST})
@GetMapping(path = "/html/demo3")
@PostMapping(path = "/html/demo4")
HATEOAS
HATEOAS(Hypermedia As The Engine Of Application State)在Json的基礎上增加了,服務發現的機制,希望入口可以把相應的RESTUrl展示出來
pom.xml 在springboot 1.5.4當中寫法如下
<!-- hateoas-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
User對象
import org.springframework.hateoas.ResourceSupport;
public class User extends ResourceSupport {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JSONRestController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@RestController
public class JSONRestController {
@Bean
public User currentUser() {
User user = new User();
user.setName("JSON");
user.setAge(20);
return user;
}
@Autowired
@Qualifier("currentUser")
private User user;
@GetMapping(path = "/json/user",
produces = MediaType.APPLICATION_JSON_VALUE)
public User user() {
user.add(linkTo(methodOn(JSONRestController.class).setUserName(user.getName())).withSelfRel());
user.add(linkTo(methodOn(JSONRestController.class).setUserAge(user.getAge())).withSelfRel());
return user;
}
//setName
@PostMapping(path = "/json/user/set/name",
produces = MediaType.APPLICATION_JSON_VALUE)
public User setUserName(@RequestParam String name) {
user.setName(name);
return user;
}
//setAge
@GetMapping(path = "/json/user/set/age",
produces = MediaType.APPLICATION_JSON_VALUE)
public User setUserAge(@RequestParam int age) {
user.setAge(age);
return user;
}
}
REST文檔生成
Spring Boot / mappings endpoin t可以看到所有的mapping相關信息
在springboot 1.5.4當中修改application.properties
endpoints.enabled = true
endpoints.sensitive = false
訪問url
http://localhost:8080/mappings
Spring RestDocs:測試化用例在編譯的時候
Swagger
REST客戶端實踐
導入pom.xml
<!-- httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
Web瀏覽器
Apache HttpClient
SpringRestTemplate
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
//String conent = restTemplate.getForObject("http://localhost:8080/json/user",String.class);
//User conent = restTemplate.getForObject("http://localhost:8080/json/user",User.class);
User conent = restTemplate.getForObject("http://localhost:8080/xml/user",User.class);
System.out.println(conent);
}