javaweb实训第六天上午——JSON&SpringMVC进阶(1)

简介: 1.课程介绍JSON; (了解)SpringMVC返回JSON; (掌握)SpringMVC文件上传、下载; (掌握)SpringMVC拦截器; (掌握)SpringMVC执行流程; (掌握)2.JSON2.1.JSON概述

1.课程介绍

  1. JSON; (了解)
  2. SpringMVC返回JSON; (掌握)
  3. SpringMVC文件上传、下载; (掌握)
  4. SpringMVC拦截器; (掌握)
  5. SpringMVC执行流程; (掌握)

2.JSON

2.1.JSON概述

在实际开发中,通常需要和别的系统交换数据,数据交换的格式通常有XML和JSON等;

JSON(JavaScript Object Notation:JavaScript对象表示法)是一种基于JavaScript 语法开放的轻量级数据交换格式,使用js语法来描述数据对象;

JSON作为一个轻量级的数据格式,相对于XML,文档更小,结构清晰简洁,读写效率更高,XML需要很多的标签,在数据传输的时候无疑会消耗更多网络资源和流量:

(1)用XML表示一个对象:

<person id="1">
<name>tom</name>
<age>20</age>
<salary>5000.0</salary>
</person>

(2)用JSON表示一个对象:{“id”:1,“name”:“tom”,“salary”:5000.0}


2.2.JSON语法

2.2.1.如何用JSON表示一个对象

简单对象:


var obj={“name”:“tom”,“age”:34}; alert(obj.name); //tom复杂对象:


var obj={“name”:“vikey”,“address”:{“city”:“成都”,“street”:“九眼桥”,“room”:“215”}}; alert(obj.address.street); //九眼桥

2.2.2.如何用JSON表示一个数组

语法:

var obj = [value,value,value]
value可以是ob

ject、数组、简单数据类型(string、number、boolean等)、json对象

例子:

var obj = [
{”id”:1,”name”:”tom1”,”salary”:5000.0},
{”id”:2,”name”:”tom2”,”salary”:6000.0},
{”id”:3,”name”:”tom3”,”salary”:7000.0}
]
alert(obj.length);
alert(obj[1].name);

遍历:

注意:json中数据的属性名必须用双引号或单引号引起来(双引号是标准格式,单引号是非标准格式),属性值如果是字符型必须用引号引起来;

2.2.3.JSON字符串和JSON对象

JSON字符串:
var obj = ‘{“id”:1,”name”:”tom”,”salary”:5000.0}’;
alert(obj.id);  X
Json对象:
var obj = {“id”:1,”name”:”tom”,”salary”:5000.0};
alert(obj.id);    //1
alert(obj.name);     //tom

3.SpringMVC返回JSON

1.有时候后台需要向前台传递JSON格式的数据,那么这个时候要把Java对象转换为JSON,就需要第三方的支持:

(1)Jackson:http://jackson.codehaus.org/

 (2)JSON-lib:http://json-lib.sourceforge.net/

 (3)Gson:http://code.google.com/p/google-gson/

 (4)FastJson阿里开源

3.1.Java对象转成JSON格式的数据

1.加入jackson工具包:

20210602161655516.png

2.后台编程(使用@ResponseBody注解):

20210602161658313.png

3.2.Json中对日期格式的特殊处理

从后台向前台:

(1)默认返回的日期格式为时间戳,而在前台我们希望显示出指定规则的日期字符串:

 默认:{“name”:“小明哥”,“birthdate”:121223223}

 期望: {“name”:“小明哥”,“birthdate”:“2025-12-12 14:12:12”}

(2)在日期get属性,字段上,添加一个格式化注解  import com.fasterxml.jackson.annotation.JsonFormat;

 @JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”,timezone=“GMT+8”)

从前台向后台:

(1)在后台模型的setter方法上,添加注解:

 @DateTimeFormat(pattern=“yyyy-MM-dd HH:mm:ss”)

(2)访问地址:localhost:8080/jsonV587?birthDay=2017-06-13 16:50:53

(3)后台接收:

@RequestMapping("/getJson")
@ResponseBody//将返回的数据自动转换成json格式的数据,而且是用了@ResponseBody,不会经过视图解析器
public Date getJson(User user){//接收的用对象接收,直接用Date类型的参数会报400(请求无效)
  System.out.println(user.getBirthday());
  return user.getBirthday();
}

3.3.注意事项

  1. 出现406状态异常:缺少jar包,加入jackson的jar包即可;
  1. 使用@ResponseBody注解之后,不会经过视图解析器;
  2. 如果在ie中测试,会弹出下载文件的窗口,可以在spring-mvc.xml的
<mvc:annotation-driven>中加入以下配置解决:
<!-- 开启spring对MVC的支持 -->
<mvc:annotation-driven>
  <!-- 避免在IE浏览器中返回JSON时出现下载文件的情况 -->
  <mvc:message-converters>
    <bean id="mappingJackson2HttpMessageConverter"
    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
      <property name="supportedMediaTypes">
        <list>
          <value>text/html;charset=UTF-8</value>
        </list>
      </property>
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>

4.文件上传与下载

4.1.文件上传

文件上传:指的是将本地的文件复制到服务器上;

SpringMvc中的文件上传是对原生文件上传的封装,目的是,较少代码量,提高开发效率;

文件上传三要素:

 (1)表单的提交的方式必须是POST请求(get请求对提交的数据)

 (2)表单中必须有一个文件上传项:,文件上传项必须有name属性和值;

 (3)表单的enctype属性的值必须是multipart/form-data

4.1.1.添加jar文件

由于SpringMVC自己没有实现文件上传,它使用的是apache.commons.fileupload

 com.springsource.org.apache.commons.fileupload-1.2.0.jar

 com.springsource.org.apache.commons.io-1.4.0.jar

4.1.2.jsp页面

20210602162722116.png

4.1.3.配置上传解析器

SpringMVC使用MultipartFile来进行文件上传,所以我们首先要配置MultipartResolver,用于处理表单中的file,如果没有配置就会报如下错误:提示告诉开发者你没有配置文件上传解析器:

配置MultipartResolver:注意id="multipartResolver"的id值不能乱写

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- 设置上传文件的最大尺寸为1MB -->
  <property name="maxUploadSize">
    <!-- spring el写法:1MB -->
    <value>#{1024*1024}</value>
  </property>
     <!-- 效果同上 -->
<property name="maxUploadSize" value="1048576" />
</bean>

4.1.4.后台处理

@Controller
public class UploadController {
  @RequestMapping(value="/upload",method=RequestMethod.POST)
  public String uploadFile(MultipartFile fileUpload,String name,HttpServletRequest req) throws FileNotFoundException, IOException {
    System.out.println("普通表单获取方式:" + name);
    //上传表单信息:注意MultipartFile对象的名称必须与上传表单项的name属性值一致
    System.out.println("上传文件是否为空:" + fileUpload.isEmpty());
    System.out.println("上传文件的大小(字节):" + fileUpload.getSize());
    System.out.println("上传文件的类型:" + fileUpload.getContentType());
    System.out.println("上传表单name属性值:" + fileUpload.getName());
    System.out.println("上传文件名:" + fileUpload.getOriginalFilename());
  // 获取upload真实路径:一大巨坑(uploadFile千万不要和请求upload一样的名字,否则第二次上传出现405)
    String realPath = req.getServletContext().getRealPath("/uploadFile");
    File file = new File(realPath);
    if (!file.exists()) {// 如果upload文件夹不存在,就创建
      file.mkdirs();
    }
    String prefix = UUID.randomUUID().toString().replaceAll("-", "");
//使用UUID加前缀命名文件,防止名字重复被覆盖
    String fileName = prefix+"_"+fileUpload.getOriginalFilename();
    InputStream in= fileUpload.getInputStream();;//声明输入输出流
    OutputStream out=new FileOutputStream(new File(realPath+"\\"+fileName));//指定输出流的位置;
    //使用IOUtils.copy实现文件复制 
    IOUtils.copy(in, out);
    System.out.println("上传成功");
    in.close();
    out.close();
    return "redirect:/upload.jsp";
  }
}

4.2.文件下载

文件下载:就是将服务器(表现在浏览器中)中的资源下载(复制)到本地磁盘;

4.2.1.前台代码

  1. 前台使用超链接,超链接转到后台控制器,在控制器通过流的方式进行操作;

20210602162838283.png

4.2.2.后台代码

@Controller
public class DownloadController {
  @RequestMapping("/download")
  public void download(String filename,HttpServletRequest req,HttpServletResponse resp) throws Exception{
    //1.获取输入流
    //1.1.获取文件在服务器的绝对路径
    String parentPath = req.getServletContext().getRealPath("/download");
    File file = new File(parentPath, filename);
    if(file.exists()){
      FileInputStream in = new FileInputStream(file);
      //2.获取输出流
      //2.1.设置文件下载的名字  -- 附件表示做下载或上传操作,浏览器就不会将文件的内容直接显示出来了
      resp.setHeader("Content-Disposition", "attachment; filename=" + filename);
      //2.2.获取输出流
      ServletOutputStream out = resp.getOutputStream();
      //3.实现下载
      IOUtils.copy(in, out);
      //关流,释放资源
      out.close();
      in.close();
    }
  }
}

4.2.3.解决中文问题

问题描述:当下载 “美女.rar”,问题就出现了?

解决方法:兼容IE、edge和其他浏览器

分析: 如果是IE或edge就用URLEncoder,如果是其他浏览器就要用以下方式解决:

new String(name.getBytes("UTF-8"),"ISO-8859-1")
user–agent:这个请求头是指用户代理的意思,告诉服务器使什么浏览器;
@Controller
public class DownloadController {
  @RequestMapping("/download")
  public void download(String filename,HttpServletRequest req,HttpServletResponse resp) throws Exception{
    //1.获取输入流
    //1.1.获取文件在服务器的绝对路径
    String parentPath = req.getServletContext().getRealPath("/download");
    File file = new File(parentPath, filename);
    if(file.exists()){
      FileInputStream in = new FileInputStream(file);
      //2.获取输出流
      //2.1.中文文件名称处理(ie和edge都是微软的浏览器 -- 处理方式一样)
//区分浏览器,User-Agent中有浏览器的信息,trident是ie引擎名称,具体:
//mozilla/5.0 (windows nt 6.2; win64; x64; trident/7.0; rv:11.0) like gecko【eclipse自带ie浏览器】
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
        //Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763【电脑安装的edge浏览器】
//mozilla/5.0 (windows nt 10.0; win64; x64; rv:68.0) gecko/20100101 firefox/68.0【火狐】
//mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/73.0.3683.86 safari/537.36【谷歌】
      //ie浏览器
      if(req.getHeader("User-Agent").toUpperCase().indexOf("TRIDENT")!=-1){
        filename = URLEncoder.encode(filename, "utf-8");
        //电脑自带edge【edʒ】浏览器  
      }else if(req.getHeader("User-Agent").toUpperCase().indexOf("EDGE")!=-1){    
        filename = URLEncoder.encode(filename, "utf-8");
      }else{//其他浏览器
        filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");//转码的方式
      };
      //2.2.设置文件下载的名字  -- 附件表示做下载或上传操作,浏览器就不会将文件的内容直接显示出来了
      resp.setHeader("Content-Disposition", "attachment; filename=" + filename);
      //2.3.获取输出流
      ServletOutputStream out = resp.getOutputStream();
      //3.实现下载
      IOUtils.copy(in, out);
      //关流,释放资源
      out.close();
      in.close();
    }
  }
}   

页面:

<a href='/download?fileName=<%=URLEncoder.encode("美女.jpg", "utf-8") %>'>美女.jpg</a>

注:Microsoft Edge和IE的最大区别就是Edge 是windows 10 之后有微软推出的浏览器,而在windows 10 之前微软系统自家浏览器都是IE;

javaweb实训第六天上午——JSON&SpringMVC进阶(2)https://developer.aliyun.com/article/1415131?spm=a2c6h.13148508.setting.32.6e1a4f0eQzpjQW

目录
相关文章
|
4月前
|
JSON JavaScript fastjson
SpringMVC原理分析 | JSON、Jackson、FastJson
SpringMVC原理分析 | JSON、Jackson、FastJson
65 0
|
4月前
|
JSON 数据格式
SpringMVC-接收请求中的json数据及日期类型参数传递
SpringMVC-接收请求中的json数据及日期类型参数传递
49 0
|
3月前
|
JSON 前端开发 Java
javaweb实训第六天上午——JSON&SpringMVC进阶(2)
5.SpringMVC拦截器 5.1.创建拦截器
53 0
|
4月前
|
JSON 数据格式
SpringMVC JSON数据交互 数据不回显问题
SpringMVC JSON数据交互 数据不回显问题
26 1
|
4月前
|
JSON 前端开发 数据格式
SpringMVC之JSON返回&异常处理机制
SpringMVC之JSON返回&异常处理机制
36 0
|
4月前
|
XML 存储 JSON
SpringMVC之JSON数据返回及异常处理机制
SpringMVC之JSON数据返回及异常处理机制
|
4月前
|
JSON 前端开发 Java
SpringMVC之JSON返回及异常处理
SpringMVC之JSON返回及异常处理
56 0
|
4月前
|
JSON 前端开发 Java
【SpringMVC】JSON数据传输与异常处理的使用
【SpringMVC】JSON数据传输与异常处理的使用
54 0
|
3月前
|
JSON PHP 数据格式
|
1月前
|
存储 JSON Apache
揭秘 Variant 数据类型:灵活应对半结构化数据,JSON查询提速超 8 倍,存储空间节省 65%
在最新发布的阿里云数据库 SelectDB 的内核 Apache Doris 2.1 新版本中,我们引入了全新的数据类型 Variant,对半结构化数据分析能力进行了全面增强。无需提前在表结构中定义具体的列,彻底改变了 Doris 过去基于 String、JSONB 等行存类型的存储和查询方式。
揭秘 Variant 数据类型:灵活应对半结构化数据,JSON查询提速超 8 倍,存储空间节省 65%