JSON&SpringMVC进阶

  • 1.课程介绍
  • 2.JSON
    • 2.1.JSON概述
    • 2.2.JSON语法
      • 2.2.1.如何用JSON表示一个对象
      • 2.2.2.如何用JSON表示一个数组
      • 2.2.3.JSON字符串和JSON对象
  • 3.SpringMVC返回JSON
    • 3.1.Java对象转成JSON格式的数据
    • 3.2.Json中对日期格式的特殊处理
    • 3.3.注意事项
  • 4.文件上传与下载
    • 4.1.文件上传
      • 4.1.1.添加jar文件
      • 4.1.2.jsp页面
      • 4.1.4.后台处理
    • 4.2.文件下载
      • 4.2.1.前台代码
      • 4.2.3.解决中文问题
  • 5.SpringMVC拦截器
    • 5.1.创建拦截器
    • 5.2.配置拦截器
  • 6.SpringMVC执行流程
    • 6.1.流程图
    • 6.2.流程描述
    • 6.3.SpringMVC工作流程描述(简易版本:面试)
  • 7.课程总结
    • 7.1.重点
    • 7.2.难点
    • 7.3.如何掌握
    • 7.4.排错技巧
  • 8.常见问题
  • 9.课后练习
  • 10.面试题
  • 11.扩展知识或课外阅读推荐(可选)
    • 11.1.扩展知识
    • 11.2.课外阅读

1.课程介绍

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

2.JSON

2.1.JSON概述

  1. 在实际开发中,通常需要和别的系统交换数据,数据交换的格式通常有XML和JSON等;
  2. JSON(JavaScript Object Notation:JavaScript对象表示法)是一种基于JavaScript 语法开放的轻量级数据交换格式,使用js语法来描述数据对象;
  3. 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工具包:

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

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包即可;
  2. 使用@ResponseBody注解之后,不会经过视图解析器;
  3. 如果在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.文件上传

  1. 文件上传:指的是将本地的文件复制到服务器上;
  2. SpringMvc中的文件上传是对原生文件上传的封装,目的是,较少代码量,提高开发效率;
  3. 文件上传三要素:
      (1)表单的提交的方式必须是POST请求(get请求对提交的数据)
      (2)表单中必须有一个文件上传项:,文件上传项必须有name属性和值;
      (3)表单的enctype属性的值必须是multipart/form-data

4.1.1.添加jar文件

  1. 由于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页面

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. 前台使用超链接,超链接转到后台控制器,在控制器通过流的方式进行操作;

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;

5.SpringMVC拦截器

5.1.创建拦截器

public class MyInterceptor implements HandlerInterceptor {//preHandle()方法在业务处理器处理请求之前被调用   @Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {System.out.println("进入拦截器了....");//这里可以判断用户是否登录 //没有登录可以使用 request/response跳转回登录页面//注:如果不继续执行返回false,否则返回truereturn false;}// postHandle()方法在业务处理器处理请求之后被调用   @Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {}// afterCompletion()方法在DispatcherServlet完全处理完请求后被调用   @Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {}
}

5.2.配置拦截器

<!-- 配置拦截器组 -->
<mvc:interceptors><!-- 拦截器 --><mvc:interceptor><!-- 要拦截的配置,该配置必须写在不拦截的上面,/*拦截一级请求,/**拦截多级请求 --><mvc:mapping path="/**"  /><!-- 设置不拦截的配置 --><mvc:exclude-mapping path="/login"/><!-- 配置拦截器 --><bean class="cn.itsource.springmvc._06_interceptor.MyInterceptor" />  </mvc:interceptor>
</mvc:interceptors>

6.SpringMVC执行流程

6.1.流程图

6.2.流程描述

注:控制器即处理器(Handler)

  1. 用户向服务器发送请求,请求会统一交给SpringMVC前端控制DispatcherServlet处理;
  2. DispatcherServlet通过请求HandlerMapping(处理器映射管理对象)找到该请求对应的Handler对象(包括控制器以及Handler对象对应的拦截器) 和HandlerExecutionChain对象(包含:控制器+2个拦截器);
  3. DispatcherServlet请求HandlerAdapter,选择一个合适的HandlerAdapter去处理Handler。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法);
  4. 提取request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
      HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
      数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
      数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
      数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
  5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
  6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet;
  7. ViewResolver 结合Model和View,来渲染视图(Model+View合成)
  8. 将渲染结果返回给客户端;

6.3.SpringMVC工作流程描述(简易版本:面试)

  1. 客户端将请求统一提交到DispatcherServlet;
  2. DispatcherServlet会将请求交给HandlerMapping进行请求映射,匹配该请求的Handler;
  3. DispatcherServlet再请求HandlerAdapter调用相应的Handler处理请求,并向前端控制器返回一个ModelAndView对象;
  4. DispatcherServlet将ModelAndView对象交给ViewResoler视图解析器处理,返回指定的视图View;
  5. DispatcherServlet 对 View 进行渲染(即将模型数据填充至视图中);
  6. DispatcherServlet 将页面响应给用户;

7.课程总结

7.1.重点

  1. SpringMvc返回Json数据;
  2. SprignMvc文件上传;
  3. SpringMvc执行流程;

7.2.难点

  1. SprignMvc文件上传;
  2. SpringMvc执行流程;

7.3.如何掌握

  1. 课上认真听课;
  2. 完成课后练习;
  3. 抓住课程重点;

7.4.排错技巧

  1. 通过异常和错误找出问题,分析问题,解决问题;
  2. 还原代码;
  3. 代码最小化;
  4. 断点;

8.常见问题

  1. 状态异常:如果出现406状态异常,jackson的jar文件没有导入
  2. HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
    分析:缺少配置

9.课后练习

  1. 课堂代码1-2遍;

10.面试题

  1. SpringMVC执行流程?

11.扩展知识或课外阅读推荐(可选)

11.1.扩展知识

拦截器(interceptor)与过滤器(filter)的区别?

  1. 拦截器与过滤器有很多相似之处,都可以拦截请求,也可以放行;
  2. 拦截器是SpringMVC中的组件,需要在Spring的配置文件中配置。而过滤器是JavaEE中的组件,在web.xml中配置。Filter的执行顺序在Interceptor之前;
  3. 拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor;

11.2.课外阅读

javaweb实训第六天上午——JSONSpringMVC进阶相关推荐

  1. javaweb实训第六天下午——Mybatis基础

    Mybatis基础 1.课程介绍 2.为什么需要Mybatis 3.初识Mybatis 3.1.Mybatis是什么 3.1.1.什么是框架 3.1.2.什么叫数据库持久化 3.1.3.什么是ORM ...

  2. java web开发实训心得,【JavaWeb实训心得体会材料】

    JavaWeb实训心得体会材料 <JavaWeb实训心得体会材料.doc>由会员分享,可免费在线阅读全文,更多与<JavaWeb实训心得体会材料>相关文档资源请在帮帮文库(ww ...

  3. [JavaWeb实训Day4]__jsoup爬虫(爬新闻页面)词云的生成( kumo库)

    目录 一.本次实验分析过程 二.Jee连接MySQL数据库 三.异步传值及界面设计 四.jsoup爬虫爬取新闻网页 五.新闻词云的生成( kumo库) 六.存入数据库 快速链接:[JavaWeb项目实 ...

  4. JavaWeb实训项目:基于SSM框架的CRM客户关系管理系统(文章最后有源码)

    JavaWeb实训项目:基于SSM框架的CRM客户关系管理系统(附部分源码) 一.项目背景 项目演示 二.项目介绍 三.涉及技术 总结 源码地址 一.项目背景 "世上本来没有CRM,大家的生 ...

  5. [JavaWeb实训Day3]__button_框架布局点击事件

    目录 一.基于JavaScript框架布局 二.button设置id 样式 三.button点击事件 快速链接:[JavaWeb项目实训]--总目录 我的运行环境在前面博客提到过,这里是在wc1项目下 ...

  6. JavaWeb实训项目 河南省旅游指南

    1 基本信息 1.1 系统名称 河南省旅游指南的设计与实现 1.2 开发运行环境 Window 10 64位 JDK 1.8.0 IDEA 2019版本 MySql 5.1.47 Tomcat 8.5 ...

  7. javaweb实训第四天上午——员工管理系统-JavaBeanELJSTLMVC思想

    目录 1.课程介绍 2.项目需求分析 3.JavaBean 3.1.什么是JavaBean 3.2.JavaBean的规范 3.3.Bean属性与对象属性 3.4.BeanUtils的使用(主要进行属 ...

  8. javaweb实训第三天上午——Servlet

    文章目录 Servlet基础 1.Servlet基础 1.1.什么是Servlet 1.2.如何开发一个Servlet 1.3.Servlet执行流程 1.4.Servlet生命周期 1.5.Serv ...

  9. javaweb实训第五天上午——Spring基础

    Spring基础 1.课程介绍 2.为什么需要Spring 3.初识Spring 3.1.什么是Spring 3.2.Spring框架的好处 3.3.Spring框架的模块化 4.Spring入门 4 ...

最新文章

  1. 软件版本命名规范(转载)
  2. 北斗导航 | 卫星导航基础知识(坐标系)
  3. 关于DubboMain启动的真相
  4. BGP小实验(二)——还是他,继续第二波走起来
  5. matplotlib可视化_使用Matplotlib改善可视化设计的5个魔术技巧
  6. python 打印皮卡丘_用python打印你的宠物小精灵吧
  7. php 数组随机排序_php 数组元素随机排序代码
  8. 大数据学习笔记06:伪分布式Hadoop
  9. java获取服务端mask_Java代码获取服务器所装office版本
  10. 最新网卡驱动下载win7
  11. QT模拟鼠标自动点击:1-鼠标移动自动显示坐标
  12. echolife hg8245说明书_华为光猫HG8245设置说明书
  13. AdventureWorks2008 数据库安装
  14. java 中文星期表示_java之获得中文星期几
  15. Windbg命令学习1(vertarget和lm和lmvm)
  16. python 音频文件 转列表 比对相似度
  17. OpenCV——图像窗口namedWindow
  18. 【随笔】记录一次简易的液位报警器的拆机修理
  19. 达人评测 i5 1155G7和i5 1135G7的差距大不大
  20. MNIST数据集的gist特征提取(含全部实例代码下载地址)

热门文章

  1. C++11 多线程线程共享数据
  2. window 创建python虚拟环境
  3. Flutter代码锦囊---切换时页面保持状态
  4. 中国内脏痛行业市场供需与战略研究报告
  5. 2021年中国等温核酸扩增技术市场趋势报告、技术动态创新及2027年市场预测
  6. SVN下载,安装,配置,常用操作 svn教程
  7. 文件上传学习:(结合upload-labs 01-12):part01
  8. SQL注入学习part01:(结合sqli-libs学习:1-10关)
  9. 为什么技术人干得越久越拿不到高薪?
  10. 华大基因辟谣“基因编辑58个婴儿”;苹果发布头戴式耳机AirPods Max;Debian 10.7发布|极客头条...