前端与后端传递数据 — — JSON

Posted NPE~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端与后端传递数据 — — JSON相关的知识,希望对你有一定的参考价值。

前端与后端传递数据 — — JSON

1 前端传送JSON数据给后端

1.1 application/x-www-form-urlencoded默认格式

1.1.1 通过HttpServletRequest获取数据

/**
  * 通过request获取数据
  * @param request
  * @return
  */
 @PostMapping("/testDefaultWithNoAnno1")
 public String testDefaultWithNoAnno1(HttpServletRequest request)
     String name = request.getParameter("name");
     System.out.println("str>>>" + name);
     return "testDefaultWithNoAnno1 success";
 

1.1.2 通过实体类获取数据

 /**
  * 通过实体类获取[Pojo]
  * @param user
  * @return
  */
 @PostMapping("/testDefaultWithNoAnno2")
 public String testDefaultWithNoAnno1(User user)
     System.out.println(user.getName() + "  " + user.getAge());
     return "testDefaultWithNoAnno2 success";
 

1.1.3 通过@RequestParam+Map获取

 /**
  * 通过Map方式+@RequestParam注解
  * @param map
  * @return
  */
 @PostMapping("/testDefaultByAnno1")
 public String testDefaultByAnno(@RequestParam Map<String, Object> map)
     String name = (String) map.get("name");
     System.out.println("name>>>" + name);
     return "testDefaultByAnno1 success";
 

1.1.4 总结

RequestMapPojo
不加注解×
@RequestParam××
@ResponseBody×××

1.2 application/json格式

注意:一般来说要通过body传送数据是使用POST方式,此处为了简单,暂用GET方式

1.2.1 传送普通字符串

@GetMapping("testJsonByStr")
public String testJSONByStr(@RequestBody String str)
    System.out.println("str>>>" + str);
    return "testJsonByStr success";

  • postman测试
  • 最后结果:

1.2.2 传送json数组

@GetMapping("/testJsonByArr")
public String testJSONByArr(@RequestBody List<String> list)
    for(String str : list)
        System.out.println("str>>>" + str);
    
    return "testJsonByArr success";

  • postman发起测试:

  • 最后结果:

1.2.3 传送json对象

//Json对象
@GetMapping("/testJsonByObj")
public String testJSONByObj(@RequestBody User user)
    System.out.println(user);
    System.out.println("name>>>" + user.getName());
    System.out.println("age>>>" + user.getAge());
    return "testJsonByObj success";

User对象(一定要有get方法):

@Data
public class User 
    private String name;
    private Integer age;

postman发起请求:

控制台消息:

User(name=张三, age=22)
name>>>张三
age>>>22

1.2.4 传送json对象数组

//Json对象数组
@GetMapping("/testJsonByObjArr")
public String testJsonByObjArr(@RequestBody List<User> userList)
    for(User user : userList)
        System.out.print("name>>>" + user.getName() + "   ");
        System.out.println("age>>>" + user.getAge());
    
    return "testJsonByObjArr success";

postman发起请求:

控制台消息:

name>>>zhangsan   age>>>23
name>>>lisi   age>>>15

1.2.5 前端的复杂请求

①编写接收类
ReqDTO

@Data
public class ReqDTO 
    private List<String> busType;
    private List<Integer> orderStatus;
    private List<String> userIds;
    //@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")一般来说也可以,但是需要精确到小时【GTM 八小时时差】
    //因此使用jackson
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startDate;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date endDate;
    private Integer start;
    private Integer limit;

②编写controller接收

@GetMapping("/testJsonByComplex")
public String testJsonByMap(@RequestBody List<ReqDTO> list)
    ReqDTO reqDTO = list.get(0);
    //busType
    List<String> busType = reqDTO.getBusType();
    for(String str : busType)
        System.out.println(str + "  ");
    
    //orderStatus
    List<Integer> orderStatus = reqDTO.getOrderStatus();
    for(Integer i : orderStatus)
        System.out.println(i + "   ");
    
    //userIds
    List<String> userIds = reqDTO.getUserIds();
    for(String id : userIds )
        System.out.println(id + "    ");
    
    //startDate
    Date startDate = reqDTO.getStartDate();
    System.out.println(startDate);
    //endDate
    Date endDate = reqDTO.getEndDate();
    System.out.println(endDate);
    //start
    Integer start = reqDTO.getStart();
    System.out.println(start);
    //limit
    Integer limit = reqDTO.getLimit();
    System.out.println(limit);
    return "testJsonByComplex success";

③postman发起请求:

④控制台结果:

appoint  
outpatient  
0   
1   
2   
11    
21    
31    
Sun Jun 20 11:43:11 CST 2021
Thu Jul 21 12:23:34 CST 2022
0
10

拓展【格式化时间的其他方式】:

private String startDate;

private String endDate;

"---------------------------------------------"
//格式化startDate
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime startDate = LocalDateTime.parse(reqDTO.getStartDate(), formatter);
System.out.println(startDate);
//endDate
LocalDateTime endDate = LocalDateTime.parse(reqDTO.getEndDate(), formatter);
System.out.println(endDate);
//start
Integer start = reqDTO.getStart();
System.out.println(start);

2 后端给前端传送JSON数据

①构建数据对象
User:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User 
    private String name;
    private Integer age;

②构建方法,返回数据

@RestController
public class JSONController 
	@GetMapping("/backToFront")
	public Map<String, Object> backToFront(@RequestBody String test)
	    Map<String, Object> result = new HashMap<>();
	    result.put("msg", "查询成功");
	    result.put("code", 200);
	    //构建数据列表
	    List<User> userList = new ArrayList<>();
	    User user1 = new User("C罗", 26);
	    User user2 = new User("梅西", 25);
	    userList.add(user1);
	    userList.add(user2);
	    result.put("data", userList);
	    return result;
	

③postman发起请求,查看响应结果

  • 如果前端传递的是:“userId”:“zhangwei”,“groupId”:131,“userOrder”:30 后端用String接收,然后JSONObject.parse(),就可以转化为JSONObject了

  • 如果前端传递的是:[“groupId”:1,“userOrder”:1,“userId”:“a’s’d”,“groupId”:1,“userOrder”:2] 后端也用String接收,然后JSONArray.parseArray(),就可以转换成JSONArray了

3 详述 application/json 与Content-Type关系

首先,application/json是Content-Type的一种。

Content-Type:在HTTP的请求头中,可以使用Content-type来指定上传参数不同格式的请求信息。

get方法:在url中说明情请求的资源,比如https://www.baidu.com/com?from=self&name=xx 其中?后的数据就是请求的数据,并且连接用&,get方法也可以提交表单数据,但是提交的数据在url中,其他人可以通过查看历史记录中的url来获取你提交的数据,这样很不安全.


post方法:传输数据不在url中,而在数据段中出现,并且请求头多了Content-Type 和 Content-Length,post提交表单数据的时候比get方法更安全.

Content-Type类型:

  • application/x-www-form-urlencoded,key&value形式,所有浏览器都支持,但是后端解析麻烦

application/x-www-form-urlencoded是默认的请求头,其ajax的请求数据格式是json

  • application/json,json串形式javascript Object Notation,后端解析简单,但部分浏览器不支持
  • multipart/form-data,主要用于文件上传,将文件转成二进制数据进行传输,不涉及转码
  • text/plain,是使用纯文本进行传输,平时用的很少

参考文章:https://blog.csdn.net/weixin_40599109/article/details/113614103

4 多级JSON解析

4.1 map类型

@SpringBootTest
public class SfTest 

    @Test
    public void testSign()
        String responseStr = "\\n" +
                "    \\"success\\": true,\\n" +
                "    \\"message\\": null,\\n" +
                "    \\"code\\": \\"velit Ut labore cillum eu\\",\\n" +
                "    \\"result\\": \\n" +
                "        \\"deliveryType\\": 1, //0:预约送达单 1:立即单 3:预约上门单\\n" +
                "        \\"expectTime\\": 1546845547, //预计送达(上门)时间\\n" +
                "        \\"startTime\\": 1546841347, //预计开始配送的时间\\n" +
                "        \\"promiseDeliveryTime\\": 70, //预计配送时间(单位: 分)\\n" +
                "        \\"deliveryDistanceMeter\\": \\"6145\\", //配送距离\\n" +
                "        \\"chargePriceList\\": \\n" +
                "            \\"shopPayPrice\\": 1200, //配送费总额(单位:分)\\n" +
                "            \\"chargesDetail\\": \\n" +
                "                \\"basicFee\\": 1100, //常规配送费=起步价+超距离费+超重量费\\n" +
                "                \\"basic\\": 900, //起步价\\n" +
                "                \\"overDistance\\": 100, //超距离费用\\n" +
                "                \\"overWeight\\": 0, //超重量费用\\n" +
                "                \\"cancelExcessFee\\": 0, //拒收扣费\\n" +
                "                \\"specialTimeFee\\": 0, //特殊时段费\\n" +
                "                \\"vasFee\\": 0, //增值服务费\\n" +
                "                \\"vasFeeDetail\\":  //增值服务费详情\\n" +
                "                    \\"packingFee\\": 0, //包材费\\n" +
                "                    \\"lowTempFee\\": 0, //低温服务费 \\n" +
                "                    \\"takeGoodsSmsFee\\": 0, //取货短信费\\n" +
                "                    \\"insured\\": \\n" +
                "                        \\"fee\\": 0, //保价费\\n" +
                "                        \\"declaredPrice\\": 0\\n" +
                "                    ,\\n" +
                "                    \\"bigOrder\\": \\n" +
                "                        \\"fee\\": 0, //大额单费\\n" +
                "                        \\"amount\\": 0\\n" +
                "                    ,\\n" +
                "                    \\"collection\\": \\n" +
                "                        \\"fee\\": 0, //代收货款费用\\n" +
                "                        \\"price\\": 0\\n" +
                "                    ,\\n" +
                "                    \\"personDirectFee\\": 0, //专人直送费用\\n" +
                "                    \\"vehicleCarFee\\": 0 //小轿车配送费用\\n" +
                "                ,\\n" +
                "                \\"extraFee\\": 0, //附加费\\n" +
                "                \\"extraFeeDetail\\": \\n" +
                "                    \\"geographyFee\\": 0\\n" +
                "                \\n" +
                "            \\n" +
                "        ,\\n" +
                "        \\"gratuityFee\\": 100, //订单小费\\n" +
                "        \\"pushTime\\": 1546841347,\\n" +
                "        //以下字段受请求参数中 return_flag 控制:return_flag中未包含的,此字段将不存在,请注意!\\n" +
                "        \\"totalPrice\\": 1300, //配送费总额,当return_flag中包含1时返回,单位分(值为计算出来此单总价)\\n" +
                "        \\"deliveryDistance_meter\\": 1234, //配送距离,当return_flag中包含2时返回,单位米(值为计算出来实际配送距离)\\n" +
                "        \\"weightGram\\": 1000, //商品重量,当return_flag中包含4时返回,单位克(值为下单传入参数回传)\\n" +
                "        \\"startTime\\": 123456789, //起送时间,当return_flag中包含8时返回,时间格式为Unix时间戳,注意转换\\n" +
                "        \\"expectTime\\": 123456789, //预计送达时间,当return_flag中包含16时返回,时间格式为Unix时间戳,注意转换\\n" +
                "        \\"totalPayMoney\\": 1300, //支付费用,当return_flag中包含32时返回,单位分\\n" +
                "        \\"realPayMoney\\": 1300,//实际支付金额,当return_flag中包含64时返回,单位分(实际支付金额=总金额-优惠券总金额)\\n" +
                "        \\"overflowFee\\": 200, //爆单费,单位分\\n" +
                "        \\"settlementType\\": 1 //结算方式,当return_flag中包含256时返回\\n" +
                "    \\n" +
                "";
        JSONObject jsonObject = JSONObject.parseObject(responseStr);
        JSONObject result = jsonObject.getJSONObject("result");
        JSONObject chargePriceList = result.getJSONObject("chargePriceList");
        Object shopPayPrice = chargePriceList.get("shopPayPrice");
        System.out.println(shopPayPrice);//1200
    

4.2 数组类型

JSONArray jsonArray = JSONArray.parseArray(priceObj.get("result").toString());

4.3 json工具的使用(fastjson为例)

①JSON(JSON.toJSONString、JSON.parseArray)

  • JSON.toJSONString
 Car car = new Car();
 car.setType("AC");
 car.setId(1);
 car.setPrePrice(true);
 car.setPrice(43.0);
 String jsonStr = JSON.toJSONString(car);
 System.out.println(jsonStr);
 //"id":1,"prePrice":true,"price":43.0,"type":"AC"

  • JSON.parseArray
 String str = "[\\n" +
         "    \\n" +
         "        \\"deliverTime\\": \\"2021-12-15 18:00:00\\",\\n" +
         "        \\"price\\": 1,\\n" +
         "        \\"businessTypeDesc\\": \\"顺丰标快\\",\\n" +
         "        \\"businessType\\": \\"2\\"\\n" +
         "    \\n" +
         "]";
 JSONArray array = JSON.parseArray(str);
 String jsonStr = JSON.toJSONString(array.get(0));
 String time = (String) JSONObject.parseObject(jsonStr).get("deliverTime");
 System.out.println(time);
 //2021-12-15 18:00:00

②JSONObject(JSONObject.parseObject、JSONObject.toJSONString)

  • JSONObject.parseObject
String str = "\\n" +
        "    \\"deliverTime\\": \\"2021-12-15 18:00:00\\",\\n" +
        "    \\"price\\": 1,\\n" +
        "    \\"businessTypeDesc\\": \\"顺丰标快\\",\\n" +
        "    \\"businessType\\": \\"2\\"\\n" +
        "";
JSONObject jsonObj = JSONObject.parseObject(str);
Object businessTypeDesc = jsonObj.get("businessTypeDesc");
System.out.println(businessTypeDesc);
//顺丰标快
  • JSONObject.toJSONString
 Car car = new Car();
 car.setType("AC");
 car.setId(1);
 car.setPrePrice(true);
 car.setPrice(43.0);

 String jsonStr = JSONObject.toJSONString(car);
 System.out.println(jsonStr);
 //"id":1,"prePrice":true,"price":43.0,"type":"AC"

JSON对象

JSON对象

  常用方法:

  1.JSON.stringify() 序列化数组,对象等

  2.JSON.parse() 反序列化

 

使用场景

  ajax与后端进行数据传递时,极其重要

  比如:在nodejs中,需要将从数据库中查找的数组传递到前端,此时需要将数组序列化成字符串;

     前端获取字符串形式的数组后,再反序列化成数组;

 

以上是关于前端与后端传递数据 — — JSON的主要内容,如果未能解决你的问题,请参考以下文章

前端与后端有哪几种ajax交互方法

前端如何高效的与后端协作开发

前端如何高效的与后端协作开发

怎么看前端有没有展示后端的数据

前端jQuery使用ajax与后端Servlet进行数据交互

前端开发与后端开发的区别是什么?