10 后端如何返回数据给前端
10 后端如何返回数据给前端
1 原生servlet
获取response的输入流,使用输入流写入数据,前端回调函数得到response的结果
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应内容类型
response.setContentType("text/html");
// 获取字符输出流
PrintWriter out = response.getWriter();
// 写入响应内容
out.println("<html>");
out.println("<head>");
out.println("<title>My Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body>");
out.println("</html>");
// 关闭输出流
out.close();
}
}
2 spring以及spring boot
注意:
- 使用ResponseBody注解直接返回对象,相当于返回200响应码,响应体是对象。
- 使用ResponseEntity,是为了自定义响应码、响应体。
选择:
- 如果你想保证响应码保持成功200,前端从json中获取真正的响应码数据,就选择用自定义类包装
- 如果你要求响应码准确,响应体就对应你的响应数据,其实响应体也可以保存为自定义类。选择ResponseEntity
方案1 使用ResponseBody注解直接返回对象
- 返回对象,对象转成json放入响应体,响应行默认响应状态码为200。
- 可以把状态码、结果描述、结果数据集作为字段封装到对象,相当于把所有信息放入响应体中,响应行状态码都是200。前端解析响应体得到真正的状态码,制作自定义错误页面。(防止客户端自动处理了错误状态码,渲染了页面)
方案2 自定义的类响应码、响应描述、响应结果数据
- 使用枚举类封装异常固定的响应码、响应描述,
- 自定义类封装响应的格式(响应码、响应描述、响应结果数据)
- 使用ResponseBody注解返回封装好的自定义类
前端解析响应体得到真正的状态码,制作自定义错误页面。(防止客户端自动处理了错误状态码,渲染了页面)
/**
* @description: 异常处理枚举类
*/
public enum ExceptionEnum implements BaseErrorInfoInterface{
// 数据操作错误定义
SUCCESS("2000", "成功!"),
BODY_NOT_MATCH("4000","请求的数据格式不符!"),
SIGNATURE_NOT_MATCH("4001","请求的数字签名不匹配!"),
NOT_FOUND("4004", "未找到该资源!"),
INTERNAL_SERVER_ERROR("5000", "服务器内部错误!"),
SERVER_BUSY("5003","服务器正忙,请稍后再试!");
//响应码、响应描述
private final String resultCode;
private final String resultMsg;
ExceptionEnum(String resultCode, String resultMsg) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
}
@Override
public String getResultCode() {
return resultCode;
}
@Override
public String getResultMsg() {
return resultMsg;
}
}
/**
* @description: 自定义数据传输
* @author: DT
* @date: 2021/4/19 21:47
* @version: v1.0
*/
public class ResultResponse {
/**
* 响应代码
*/
private String code;
/**
* 响应消息
*/
private String message;
/**
* 响应结果
*/
private Object result;
public ResultResponse() {
}
public ResultResponse(BaseErrorInfoInterface errorInfo) {
this.code = errorInfo.getResultCode();
this.message = errorInfo.getResultMsg();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
/**
* 成功
* @return
*/
public static ResultResponse success() {
return success(null);
}
public static ResultResponse success(Object data) {
ResultResponse rb = new ResultResponse();
rb.setCode(ExceptionEnum.SUCCESS.getResultCode());
rb.setMessage(ExceptionEnum.SUCCESS.getResultMsg());
rb.setResult(data);
return rb;
}
/**
* 失败
*/
public static ResultResponse error(BaseErrorInfoInterface errorInfo) {
ResultResponse rb = new ResultResponse();
rb.setCode(errorInfo.getResultCode());
rb.setMessage(errorInfo.getResultMsg());
rb.setResult(null);
return rb;
}
public static ResultResponse error(String code, String message) {
ResultResponse rb = new ResultResponse();
rb.setCode(code);
rb.setMessage(message);
rb.setResult(null);
return rb;
}
public static ResultResponse error( String message) {
ResultResponse rb = new ResultResponse();
rb.setCode("-1");
rb.setMessage(message);
rb.setResult(null);
return rb;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
使用controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/custom")
public ResultResponse<String> customResponse() {
return ResultResponse.success();
}
}
方案3 返回ResponseEntity:
返回ResponseEntity对象,ResponseEntity对象自定义响应行、响应头、响应体,更精细地控制响应。
原理:
- ResponseEntity继承了 HttpEntity 类,HttpEntity 代表一个 HTTP 请求或者响应实体,包括状态码,响应头和响应体。
- responseEntity就是层包装,最终还是写入到Tomcat(Servlet容器)的响应对象。由serlvet容器把响应通过连接器处理后给前端.
ResponseEntity常用方法:
1 使用ResponseEntity.ok()方法:传入响应体
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/custom")
public ResponseEntity<String> customResponse() {
//使用ResponseEntiry的静态方法,默认状态码200,pageinfo是分页数据
return ResponseEntity.ok(pageInfo);
}
}
2 ResponseEntity静态方法:传入状态码、响应头、响应体
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/custom")
public ResponseEntity<String> customResponse() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.header("Content-Disposition", "attachment; filename=\"sample.pdf\"")
.body("Custom error message");
}
}
3 ResponseEntity的构造函数:传入状态码、响应头、响应体
//创建响应头对象,并添加头信息
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
//使用ResponseEntity的构造函数(响应体、响应头、响应状态码)
return new ResponseEntity<>(pageInfo,headers,HttpStatus.resolve(200));
HttpStatus状态码
方式1 通过数字状态码
return new ResponseEntity<>(HttpStatus.resolve(400));
方式2 通过枚举类型
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
HttpStaus枚举类常用状态码对应表:
枚举属性 状态码
CONTINUE 100
OK 200
CREATED 201
NO_CONTENT 204
PARTIAL_CONTENT 206
MOVED_PERMANENTLY 301
FOUND 302
NOT_MODIFIED 304
BAD_REQUEST 400
UNAUTHORIZED 401
FORBIDDEN 403
NOT_FOUND 404
INTERNAL_SERVER_ERROR 500
SERVICE_UNAVAILABLE 503

浙公网安备 33010602011771号