SpringMVC ----Json的简单交互处理

标签: SpringMVC  json  spring

Json的介绍

什么是JSON?

  • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:

  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组
{"age":20,"name":"张三","sex":"男"}

//或者用数组保存    两边有一个方括号

[{"age":20,"name":"张三1","sex":"男"},
 {"age":20,"name":"张三2","sex":"男"},
 {"age":20,"name":"张三3","sex":"男"},
 {"age":20,"name":"张三4","sex":"男"},
 {"age":20,"name":"张三5","sex":"男"}]

很多人搞不清楚 JSON 和 JavaScript 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:

JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

var jsobj = {name: '张三', age: 20}; //这是一个js对象,注意键名也是可以使用引号包裹的
var json = '{"name": "张三", "age": 20}'; //这是一个 JSON 字符串,本质是一个字符串

JSON 和 JavaScript 对象互转

  • 要实现从JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法
  • 要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法

先举个简单的例子,应该看得懂下面的js代码吧,基本得不能再基本了

<script type="text/javascript">
	//编写一个js的对象
    var user = {
        name: "张三",
        age: 20,
        sex: "男"
    }
    //将js对象转换成json字符串
    var json = JSON.stringify(user);
    console.log(json);
    document.write("将js对象转换成json字符串" + json + "<br><br>");

    //将json字符串转换为js对象
    var jsobj = JSON.parse(json);
    document.write("将json字符串转换为js对象" + jsobj)
    console.log(jsobj);
</script>

运行结果如下:

在这里插入图片描述

Controller返回JSON数据

Jackson

Jackson应该是目前比较好的json解析工具了

当然工具不止这一个,比如还有阿里巴巴的 fastjson 等等。

我们这里使用Jackson,使用它需要导入它的jar包

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.10.0</version>
</dependency>

配置SpringMVC需要的配置(每建一个maven项目都可以直接拿来用的)

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
       <servlet-name>SpringMVC</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>

   <filter>
       <filter-name>encoding</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
           <param-name>encoding</param-name>
           <param-value>utf-8</param-value>
       </init-param>
   </filter>
   <filter-mapping>
       <filter-name>encoding</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>

</web-app>

springmvc-servlet.xml (使用注解开发的也是直接拿来就用)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

   <!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
   <context:component-scan base-package="controller"/>

   <!-- 视图解析器 -->
   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
         id="internalResourceViewResolver">
       <!-- 前缀 -->
       <property name="prefix" value="/WEB-INF/jsp/" />
       <!-- 后缀 -->
       <property name="suffix" value=".jsp" />
   </bean>

</beans>

我们随便编写一个User的实体类,然后我们去编写我们的测试Controller;

package pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//需要导入lombok依赖
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   private String name;
   private int age;
   private String sex;
}

这里我们需要两个新东西,一个是@ResponseBody,一个是ObjectMapper对象,我们看下具体的用法

编写一个UserController

package controller;

@Controller
public class UserController {
	@RequestMapping("/j1")
    @ResponseBody
    public String json1() throws JsonProcessingException {
        //创建一个jackson的对象映射器,用来解析数据
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user = new User("张三", 20, "男");
        //将我们的对象解析成为json格式
        String str = mapper.writeValueAsString(user);
        //由于@ResponseBody注解,它就不会走视图解析器,直接返回一个字符串,所以这里会将str直接返回
        return str;
   }
}

启动Tomcat运行下,结果
在这里插入图片描述
呃,我这里没有出现乱码,由于我现在的已经配置好了再写的博客,所以无伤打雅

乱码

乱码的解决方法一

开始的映射路径是这样:

@RequestMapping("/j1")

改成下面这样就OK了

//produces:指定响应体返回类型和编码
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")

所以处理JSON时候要注意乱码问题,下面还提供了统一解决的方法

代码优化

乱码统一解决方法

上一种方法比较麻烦,如果项目中有许多请求则每一个都要添加,可以通过Spring配置统一指定,这样就不用每次都去处理了!

我们可以在springmvc的配置文件上添加一段消息StringHttpMessageConverter转换配置!

<mvc:annotation-driven>
   <mvc:message-converters register-defaults="true">
       <bean class="org.springframework.http.converter.StringHttpMessageConverter">
           <constructor-arg value="UTF-8"/>
       </bean>
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <property name="objectMapper">
               <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                   <property name="failOnEmptyBeans" value="false"/>
               </bean>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

注意在springmvc的配置文件的开头加入这玩意儿,一些工具会自动导入
在这里插入图片描述

返回json字符串统一解决

在类上直接使用 @RestController ,这样子,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !我们在前后端分离开发中,一般都使用 @RestController ,十分便捷!

@RestController
public class UserController {

   @RequestMapping(value = "/j1")
   public String json1() throws JsonProcessingException {
       //创建一个jackson的对象映射器,用来解析数据
       ObjectMapper mapper = new ObjectMapper();
       //创建一个对象
       User user = new User("张三", 20, "男");
       //将我们的对象解析成为json格式
       String str = mapper.writeValueAsString(user);
       //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
       return str;
  }
}

先启动Tomcat测试一下,结果还是正常输出!

测试多个对象的集合输出

在UserController添加一个方法

// 多个对象
@RequestMapping(value = "/j2")
public String json2() throws JsonProcessingException {
	List<User> userList = new ArrayList<User>();
	User user1 = new User("张三1", 20, "男");
	User user2 = new User("张三2", 20, "男");
	User user3 = new User("张三3", 20, "男");
	User user4 = new User("张三4", 20, "男");
	User user5 = new User("张三5", 20, "男");
	userList.add(user1);
	userList.add(user2);
	userList.add(user3);
	userList.add(user4);
	userList.add(user5);
	
	//将我们的对象解析成为json格式
   String strs = mapper.writeValueAsString(userList);
   return strs;
}

运行结果:
在这里插入图片描述

输出时间对象

增加一个新的方法

@RequestMapping("/j3")
public String json3() throws JsonProcessingException {
   ObjectMapper mapper = new ObjectMapper();
   //创建时间一个对象,java.util.Date下的,别导成sql下的了
   Date date = new Date();
   //将我们的对象解析成为json格式
   String str = mapper.writeValueAsString(date);
   return str;
}

结果:
在这里插入图片描述

  • 默认日期格式会变成一个数字,是1970年1月1日到当前日期的毫秒数!
  • Jackson 默认是会把时间转成时间戳timestamps形式

解决方案:取消timestamps形式 , 自定义时间格式

@RequestMapping("/j3")
public String json3() throws JsonProcessingException {

   ObjectMapper mapper = new ObjectMapper();

   //不使用时间戳的方式
   mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
   //自定义日期格式对象
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   //指定日期格式
   mapper.setDateFormat(sdf);

   Date date = new Date();
   String str = mapper.writeValueAsString(date);

   return str;
}

运行结果

在这里插入图片描述

抽取为工具类

如果要经常使用的话,这样是比较麻烦的,我们可以将这些代码封装到一个工具类中;我们去编写下

package utils;

import java.text.SimpleDateFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class JsonUtils {
	//当只传入一个参数的时候调用下面的方法,并且有一个默认的日期格式
	public static String getJson(Object object) {
		return getJson(object, "yyyy-MM-dd HH:mm:ss");
	}
	
	public static String getJson(Object object, String dateFormat) {
		ObjectMapper mapper = new ObjectMapper();

		// 不使用时间戳的方式
		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		// 自定义日期的格式
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);

		mapper.setDateFormat(sdf);

		try {
			//直接返回处理后的Json字符串
			return mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return null;
	}
}

我们使用工具类,代码就更加简洁了!

返回一个时间

@RequestMapping("/j4")
public String json4() throws JsonProcessingException {
   Date date = new Date();
   return JsonUtils.getJson(date);
}

@RequestMapping(value = "/j5")
public String json5() throws JsonProcessingException {
	Date date = new Date();
	return JsonUtils.getJson(date, "yyyy-MM-dd HH:mm:ss");
}

返回一个对象和返回多个对象

@RequestMapping(value = "/j6")
public String json6() throws JsonProcessingException {
	User user = new User("张三", 20, "男");
	return JsonUtils.getJson(user);
}
// 多个对象
@RequestMapping(value = "/j7")
public String json7() throws JsonProcessingException {
	List<User> userList = new ArrayList<User>();
	User user1 = new User("张三1", 20, "男");
	User user2 = new User("张三2", 20, "男");
	User user3 = new User("张三3", 20, "男");
	User user4 = new User("张三4", 20, "男");
	User user5 = new User("张三5", 20, "男");
	userList.add(user1);
	userList.add(user2);
	userList.add(user3);
	userList.add(user4);
	userList.add(user5);
	
	return JsonUtils.getJson(userList);
}

输出结果和上面都是一样的

FastJson

fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。

fastjson 的 pom依赖!

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.73</version>
</dependency>

fastjson 三个主要的类:

JSONObject

代表 json 对象

  • JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
  • JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。

JSONArray

代表 json 对象数组

  • 内部是有List接口中的方法来完成操作的。

JSON

代表 JSONObject和JSONArray的转化

  • JSON类源码分析与使用
  • 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。

代码测试,

我们新建一个FastJsonDemo 类

package controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import pojo.User;
import java.util.ArrayList;
import java.util.List;

@RestController 
public class FastJsonDemo {
	@RequestMapping("fj1")
	public String fastjson1() {
		List<User> userList = new ArrayList<User>();
		User user1 = new User("张三1", 20, "男");
		User user2 = new User("张三2", 20, "男");
		User user3 = new User("张三3", 20, "男");
		User user4 = new User("张三4", 20, "男");
		User user5 = new User("张三5", 20, "男");
		userList.add(user1);
		userList.add(user2);
		userList.add(user3);
		userList.add(user4);
		userList.add(user5);

		System.out.println("*******Java对象 转 JSON字符串*******");
		String str1 = JSON.toJSONString(userList);
		System.out.println("JSON.toJSONString(list)==>" + str1);
		String str2 = JSON.toJSONString(user1);
		System.out.println("JSON.toJSONString(user1)==>" + str2);

		System.out.println("\n****** JSON字符串 转 Java对象*******");
		User jp_user1 = JSON.parseObject(str2, User.class);
		System.out.println("JSON.parseObject(str2,User.class)==>" + jp_user1);

		System.out.println("\n****** Java对象 转 JSON对象 ******");
		JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
		System.out.println("(JSONObject) JSON.toJSON(user2)==>" + jsonObject1.getString("name"));

		System.out.println("\n****** JSON对象 转 Java对象 ******");
		User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
		System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>" + to_java_user);
		return "test";
	}
}

结果
在这里插入图片描述
这种工具类,我们只需要掌握使用就好了,在使用的时候在根据具体的业务去找对应的实现。和以前的commons-io那种下载文件的工具包一样,拿来用就好了!

版权声明:本文为wulei2921625957原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wulei2921625957/article/details/107764382

智能推荐

Rtthread学习笔记(十三)RT-Thread Studio开启硬件看门狗Watchdog

一、开启硬件看门狗Watchdog 1、配置RT-Thread Settings 2、开启stm32f1xx_hal_conf.h中的宏定义 3.使用RT接口函数初始化硬件看门狗...

TYVJ 4864 天天去哪吃 || 清北学堂金秋杯大奖赛

题目描述: 记录一下i这个值上次出现的位置在哪里,就是pre...

java反编译

jvm 把Boolean类型的值flag当做int类型处理。​​​ Foo.java: 由 class 文件生成 jasm 文件:java -jar asmtools.jar jdis Foo.class > Foo.jasm  修改jasm文件: 执行反编译: java -jar jd-gui-1.6.6.jar File 打开Foo.class文件:b修改为2 重新执行java...

【学习笔记】03-v-html的学习和示例

v-html的认识和使用 示例: 显示结果: 注意:v-html是有复制的...

Java实现在线考试系统(系统介绍)

1.和现在有的考试系统有以下几种优势: a.和现在有的系统比较起来,本系统有科目、章节、老师、学生、班级等信息的管理,还有批阅试卷查看已批阅试卷等。传统的考试系统划分并不细,业务功能简单。 b.和学校的考试系统还有外面的考试系统比较起来,本系统是B/S结构,学校的考试系统一般为C/S结构,性能方面不如B/S结构,并且C/S接口需要安装客户端,客户端压力很大,我的系统只需要电脑具有浏览器,在同一局域...

猜你喜欢

计算机视觉--多视几何初步尝试

基础矩阵的原理 K和K’分别是两个相机的参数矩阵。p和p’是X在平面π的坐标表示。所以可以得出 具体计算过程 代码: #!/usr/bin/env python coding: utf-8 from PIL import Image from numpy import * from pylab import * import numpy as np from imp ...

java初学者怎么学习才可以快速入门

java初学者怎么学习才可以快速入门 一、了解JAVA 我们要知道:Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言。 Java之父:詹姆斯·高斯林 1.1 java的三个体系 Java SE(Java Platform Standard Edition)。Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境...

字段属性之主键&增删改查&自增长&唯一键约束

字段属性之主键&自增长&唯一键约束 主键 主键:primary key 主要的键 一张表中只有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,不能重复,这种称之为主键 一张表只能最多一个主键 增加主键 SQL操作中有多种方式增加主键大体分为三种 1.在创建表的时候直接在字段之后跟primary key关键字(主键本身不允许为空) 优点:非常直接:缺点:只能使用一个字段作为...

linux下 基于libmad的socket多用户mp3音频在线播放服务器

在众多大神的帮助下,这个在线播放流媒体服务器终于完成啦。。。。 这个mp3流媒体服务器设计的思路是,服务器程序server用多线程实现和多个客户端的通信(这是必然的),然后发送给客户端当前的音频列表公客户端选择,之后根据k客户端的选择给多个客户端传输相应mp3文件的数据,同时,客户端进行实时地音频解码并播放。 关于libmad开源mp3音频解码库的使用,见上一篇博客吧。。。。 在服务器程序这一端,...

Nginx

Nginx Nginx简介: Nginx是一个高性能的http和反向代理服务器,特点是有内存少,并发能力强,事实上Nginx的并发能力确实在同类型网页服务器中表现较好, Nginx用作web服务器:Nginx可以作为静态页面的web服务器,同时还支持CGI语言,但不支持java,java程序只能通过Tomcat配合完成。Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受...