1.REST的含义:
REST全称表述性状态转移(Representational State Transfer),REST重点关注的是资源,资源可以是各种形式,JSON, XML, HTML等。它涉及到转移资源数据,以某种表述性形式从一个应用转移到另一个应用。REST包含4种行为,对应CURD,Create: POST, Read: GET, Update:PUT OR PATCH, Delete:DELETE。
2.Spring对REST的集成支持
1)控制器可以处理所有的HTTP方法,包含REST的4种行为:POST, GET, PUT, DELETE。
2)借助@PathVariable注解,控制器能够处理参数化的URL;
3)借助Spring的视图处理器,资源能够以多种形式表述,将数据转化为JSON, XML, HTML等形式。
4)借助@RequestBody注解和HttpMethodConverter可以将传入的HTTP数据传到控制器转化为相应的Java对象。
5)借助Spring封装的RestTemplate对象,Spring能够通过请求获取资源。
3.代码示例,创建REST服务端
控制层:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.List;
@Controller
@RequestMapping
public class RestServerDemo {
@RequestMapping(method = RequestMethod.GET, produces = "application/json") //只输出输出json对象
@ResponseBody // 告诉消息器将java对象转换为表述
public List spittles(@RequestParam(value = "max", defaultValue = "1000") long max,
@RequestParam(value = "count", defaultValue = "20") int count) {
//自行添加业务逻辑
}
@RequestMapping(method = RequestMethod.POST, consumes = "application/json") //只接受接受json对象
@ResponseBody // 告诉消息器将java对象转换为表述
public void saveSpittles(@RequestBody String str, UriComponentsBuilder ucb) {
//在响应中设置头部信息,返回资源的位置
//ucb对象可以动态地获取项目的根路径,避免硬编码
HttpHeaders headers = new HttpHeaders();
URI uri = ucb.path("资源路径").build().toUri();
headers.setLocation(uri);
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);//返回形式,但是似乎会出错,可能和Spring版本有关系
ResponseEntity responseEntity = new ResponseEntity(放置的对象,headers,HttpStatus.CREATED);
}
//返送错误信息到客户端,当返回是空时,404错误码
//尽量不要再控制层使用泛型,否则留下犯错的空间
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<String> spittleById(@PathVariable long id) {
//查询对象
//该对象是空
if (null == null) {
throw new SpittleNotFoundException(id);
}
return new ResponseEntity<String>("放置返回的对象", HttpStatus.OK);
}
//用于抛出异常时使用
@ExceptionHandler(SpittleNotFoundException.class)
public ResponseEntity<ErrorDemo> spittleNotFound(SpittleNotFoundException e) {
long id = e.getId();
ErrorDemo error = new ErrorDemo(4, " ");
return new ResponseEntity<ErrorDemo>(error, HttpStatus.NOT_FOUND);
}
}
自定义异常类:
import lombok.Getter;
@Getter
public class SpittleNotFoundException extends RuntimeException {
private Long id;
public SpittleNotFoundException(Long id) {
this.id = id;
}
}
异常信息封装类
@Data
public class ErrorDemo {
private int code;
private String message;
public ErrorDemo(int code, String message) {
this.code = code;
this.message = message;
}
}
4.代码示例,创建REST客户端
1)原生的HTTP请求代码
import java.io.IOException;
public class RestClientDemo {
public <T> T fetchFaceBooProfile(String id){
HttpClient client = HttpClients.createDefault();//创建客户端
HttpGet request = new HttpGet("请求地址"+id);
T obj = null ;
try {
HttpResponse response = client.execute(request);//执行请求
HttpEntity entity = response.getEntity();
ObjectMapper mapper = new ObjectMapper();
return obj = mapper.readValue(entity.getContent(),T.class);
} catch (IOException e) {
e.printStackTrace();
}
return obj;
}
}
缺点是存在大量的样板代码。借助Spring的RestTemplate对象可以大大消除调样板代码。下面介绍RestTemplate对象。
2)RestTemplate對象的GET资源请求
<T> T getForObject(String var1, Class<T> var2, Object... var3) throws RestClientException;
<T> T getForObject(String var1, Class<T> var2, Map<String, ?> var3) throws RestClientException;
<T> T getForObject(URI var1, Class<T> var2) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String var1, Class<T> var2, Object... var3) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String var1, Class<T> var2, Map<String, ?> var3) throws RestClientException;
<T> ResponseEntity<T> getForEntity(URI var1, Class<T> var2) throws RestClientException;
代码示例:
import org.springframework.web.client.RestTemplate;
import javax.print.DocFlavor;
import java.util.HashMap;
import java.util.Map;
public class RestClientDemo1 {
public <T> T fetchFaceBooProfile(String id){
Map<String,String> urlValue = new HashMap<>();
urlValue.put("id",id);
Class<T> object = ....;
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject("请求地址/{动态参数}",object.class(),urlValue);
}
}
其他的还有PUT, DELETE, POST资源操作,大体类似,具体参照RestTemplate对象API。
参考文献:
1.百度
2.Spring实战(第四版)