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

posted @ 2025-04-01 00:49  mikuc3c  阅读(263)  评论(0)    收藏  举报