ResponseEntity
- 简介:继承自HttPEntity类,封装了请求后返回的响应头、响应体和响应状态。
- 作用:用于controller层向前端返回数据和状态码。
- 构造器:
- new ResponseEntity(HttpStatus.OK): http状态码。
- new ResponseEntity(new User(),HttpStatus.OK): 泛型对象的数据和http状态码。
- new ResponseEntity(MultiValueMap
headers, HttpStatus statusCode):http首部(如,HttpHeaders类)和状态码。 - new ResponseEntity(new User(), MultiValueMap
headers, HttpStatus statusCode) - 示例:
@RequestMapping(value="/response/entity/status", method=RequestMethod.GET)
public ResponseEntity responseEntityStatusCode() {
return new ResponseEntity("The String ResponseBody with
custom status code (403 Forbidden)",
HttpStatus.FORBIDDEN);
}
- 以上方法相当于以下@ResponseBody+@ResponseStatus,它会返回@RequestMapping原页面,显示字符串,并带回一个状态码:
@RequestMapping(value="/response/entity/status", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.FORBIDDEN)
public String responseEntityStatusCode() {
return "The String ResponseBody with
custom status code (403 Forbidden)",
}
- 虽然这里将状态码设为HttpStatus.FORBIDDEN,但是字符串仍能正常显示在页面上,那么HttpStatus.FORBIDDEN起什么作用呢?
- 我们配合RestTemplate写个例子,对该url发起访问,运行结果显示,发起请求失败,后台抛出402异常,但前端照常显示字符串:
public static void main(String[] args) {
RestTemplate template = new RestTemplate();
//调用getForEntity抛出异常
ResponseEntity entity = template.getForEntity(
"http://localhost:8080/web/response/entity/status", String.class);
String body = entity.getBody();
MediaType contentType = entity.getHeaders().getContentType();
HttpStatus statusCode = entity.getStatusCode();
System.out.println("statusCode:[" + statusCode + "]");
}
- 异常日志:
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler
.handleError(DefaultResponseErrorHandler.java:76)
at org.springframework.web.client.RestTemplate.handleResponseError(
RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(
RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.getForEntity(
RestTemplate.java:221)
at org.springframework.samples.mvc.response.ResponseControllerTest.main(
ResponseControllerTest.java:12)
- 回到ResponseEntity构造器的测试,以下代码进一步指定返回内容的content-type为text/plain。
@RequestMapping(value="/response/entity/headers", method=RequestMethod.GET)
public ResponseEntity responseEntityCustomHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity("The String ResponseBody with
custom header Content-Type=text/plain",
headers, //指定content-type
HttpStatus.OK);
}
- 参考文章
- 代码示例:ideaProjects/shiro-cahpter17/web/AuthorizeController
RestTemplate
- Spring提供的用于访问Rest服务器的客户端。通常用于模拟请求,分析返回的响应数据。
- 方法:
- getForEntity():发送get请求,返回ResponseEntity类,包含了响应体所映射成的对象,比如,响应体数据为一个由User转化的json,那么它被封装进ResponseEntity时将转回User对象。我们用一个ResponseEntity对象接收该方法返回值后,可取出其中的响应体对象、响应头和响应状态。
- getForObject():同上,不过只返回User对象。
- postForEntity():post请求。
- postForObject():post请求。
- delete():在特定的URL上对资源执行HTTP DELETE操作。
- exchange():在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的。
- execute():在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象。
- headForHeaders():发送HTTP HEAD请求,返回包含特定资源URL的HTTP头。
- optionsForAllow():发送HTTP OPTIONS请求,返回对特定URL的Allow头信息。
- postForLocation():POST 数据到一个URL,返回新创建资源的URL。
- put():PUT 资源到特定的URL。
getForEntity()
- getForEntity(String url,Class responseType,Map
uriVariables/Object… uriVariables):目标url,响应体映射的对象,url参数(0个或多个)。
/**
* 将要被请求的controller
**/
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "getAll")
public List getUser() {
List list = userService.getAll();
return list;
}
}
/**
* 模拟请求的controller
**/
@RestController
public class UserController {
@RequestMapping("getForEntity")
public List getAll2() {
//模拟请求并获取响应数据
ResponseEntity responseEntity =
restTemplate.getForEntity("http://localhost/getAll", List.class);
//获取响应头
HttpHeaders headers = responseEntity.getHeaders();
//响应状态
HttpStatus statusCode = responseEntity.getStatusCode();
int code = statusCode.value();
//响应体
List list = responseEntity.getBody();
System.out.println(list.toString());
return list;
}
}
- 有参数的getForEntity(),可以使用{}先在url中占位,然后在方法最后一位参数补上此url参数:
//待请求的controller类中
@RequestMapping("get/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) {
return userService.getById(id);
}
//模拟请求的controller
@RequestMapping("getForEntity/{id}")
public UserEntity getById2(@PathVariable(name = "id") String id) {
//模拟带参数的get请求
ResponseEntity responseEntity = restTemplate.getForEntity(
"http://localhost/get/{id}", UserEntity.class, id); //Object...形式的参数
/*也可采用Map形式的参数
* HashMap map = new HashMap<>();
* map.put("id",id);
* ResponseEntity responseEntity = restTemplate.getForEntity(
* "http://localhost/get/{id}", UserEntity.class, map);
*/
UserEntity userEntity = responseEntity.getBody();
return userEntity;
}
- getForEntity(URI uri,Class responseType): 不做测试了。
getForObject()
- 有的时候不需要全部的响应数据,只要响应体就足够了。
- getForObject(URI uri,Class responseType)。
- getForObject(String url.Class responseType,Map
/Object… uriVariables):
//无参数的 getForObject 请求
@RequestMapping("getAll2")
public List getAll() {
List list = restTemplate.getForObject("http://localhost/getAll",
List.class);
System.out.println(list.toString());
return list;
}
//有参数的 getForObject 请求
@RequestMapping("get2/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) {
//使用Object...形式的参数
UserEntity userEntity = restTemplate.getForObject(
"http://localhost/get/{id}", UserEntity.class, id);
/*也可使用Map形式
* HashMap map = new HashMap<>();
* map.put("id",id);
* UserEntity userEntity = * restTemplate.getForObject(
* "http://localhost/get/{id}", UserEntity.class, map);
*/
return userEntity;
}
postForEntity()
- postForEntity(String url,Object request,Class responseType,Map
/Object… uriVariables): url,request:要放在post报体中的参数;响应体映射的实体,url参数。
@RequestMapping(value = "save")
public String save(UserEntity userEntity) {
return "保存成功";
}
//post 请求,提交 UserEntity 对象
@RequestMapping("saveUser")
public String save(UserEntity userEntity) {
ResponseEntity responseEntity = restTemplate.postForEntity(
"http://localhost/save", userEntity, String.class);
String body = responseEntity.getBody();
return body;
}
- 浏览器访问http://localhost/saveUser?username=itguang&password=123456&age=20&email=123@123.com,后面参数将被自动封装到UserEntity中传入方法。提交的数据和请求后返回的ResponseEntity如下:
- 有参数的postForEntity():
@RequestMapping(value = "saveByType/{type}") //type实际并非参数,而是url的一部分
public String saveByType(UserEntity userEntity,
@PathVariable("type")String type) { //但是它要作为参数传给方法使用
return "保存成功,type="+type;
}
@RequestMapping("saveUserByType/{type}")
public String save2(UserEntity userEntity,@PathVariable("type")String type) {
//使用Object...形式传参,也可使用Map
ResponseEntity responseEntity = restTemplate.postForEntity(
"http://localhost/saveByType/{type}", userEntity, String.class, type);
String body = responseEntity.getBody();
return body;
}
浏览器访问localhost/saveUserByType/120?username=itguang&password=123456&age=20&email=123@123.com,返回:保存成功,type=120.
参考文章
HttpStatus.FORBIDDEN起什么作用呢
- 前面ResponseEntity第一个例子将状态码设为HttpStatus.FORBIDDEN,但是字符串仍能正常显示在页面上,那么HttpStatus.FORBIDDEN起什么作用呢?
- 我们配合RestTemplate写个例子,对该url发起访问,运行结果显示,发起请求失败,后台抛出402异常,但前端照常显示字符串:
public static void main(String[] args) {
RestTemplate template = new RestTemplate();
//调用getForEntity抛出异常
ResponseEntity entity = template.getForEntity(
"http://localhost:8080/web/response/entity/status", String.class);
String body = entity.getBody();
MediaType contentType = entity.getHeaders().getContentType();
HttpStatus statusCode = entity.getStatusCode();
System.out.println("statusCode:[" + statusCode + "]");
}
- 异常日志:
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler
.handleError(DefaultResponseErrorHandler.java:76)
at org.springframework.web.client.RestTemplate.handleResponseError(
RestTemplate.java:486)
at org.springframework.web.client.RestTemplate.doExecute(
RestTemplate.java:443)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.getForEntity(
RestTemplate.java:221)
at org.springframework.samples.mvc.response.ResponseControllerTest.main(
ResponseControllerTest.java:12)