javaweb实训第六天上午——JSONSpringMVC进阶
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.课程介绍
- JSON; (了解)
- SpringMVC返回JSON; (掌握)
- SpringMVC文件上传、下载; (掌握)
- SpringMVC拦截器; (掌握)
- 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工具包:
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.注意事项
- 出现406状态异常:缺少jar包,加入jackson的jar包即可;
- 使用@ResponseBody注解之后,不会经过视图解析器;
- 如果在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页面
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.前台代码
- 前台使用超链接,超链接转到后台控制器,在控制器通过流的方式进行操作;
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)
- 用户向服务器发送请求,请求会统一交给SpringMVC前端控制DispatcherServlet处理;
- DispatcherServlet通过请求HandlerMapping(处理器映射管理对象)找到该请求对应的Handler对象(包括控制器以及Handler对象对应的拦截器) 和HandlerExecutionChain对象(包含:控制器+2个拦截器);
- DispatcherServlet请求HandlerAdapter,选择一个合适的HandlerAdapter去处理Handler。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法);
- 提取request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中 - Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
- 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet;
- ViewResolver 结合Model和View,来渲染视图(Model+View合成)
- 将渲染结果返回给客户端;
6.3.SpringMVC工作流程描述(简易版本:面试)
- 客户端将请求统一提交到DispatcherServlet;
- DispatcherServlet会将请求交给HandlerMapping进行请求映射,匹配该请求的Handler;
- DispatcherServlet再请求HandlerAdapter调用相应的Handler处理请求,并向前端控制器返回一个ModelAndView对象;
- DispatcherServlet将ModelAndView对象交给ViewResoler视图解析器处理,返回指定的视图View;
- DispatcherServlet 对 View 进行渲染(即将模型数据填充至视图中);
- DispatcherServlet 将页面响应给用户;
7.课程总结
7.1.重点
- SpringMvc返回Json数据;
- SprignMvc文件上传;
- SpringMvc执行流程;
7.2.难点
- SprignMvc文件上传;
- SpringMvc执行流程;
7.3.如何掌握
- 课上认真听课;
- 完成课后练习;
- 抓住课程重点;
7.4.排错技巧
- 通过异常和错误找出问题,分析问题,解决问题;
- 还原代码;
- 代码最小化;
- 断点;
8.常见问题
- 状态异常:如果出现406状态异常,jackson的jar文件没有导入
- HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
分析:缺少配置
9.课后练习
- 课堂代码1-2遍;
10.面试题
- SpringMVC执行流程?
11.扩展知识或课外阅读推荐(可选)
11.1.扩展知识
拦截器(interceptor)与过滤器(filter)的区别?
- 拦截器与过滤器有很多相似之处,都可以拦截请求,也可以放行;
- 拦截器是SpringMVC中的组件,需要在Spring的配置文件中配置。而过滤器是JavaEE中的组件,在web.xml中配置。Filter的执行顺序在Interceptor之前;
- 拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor;
11.2.课外阅读
javaweb实训第六天上午——JSONSpringMVC进阶相关推荐
- javaweb实训第六天下午——Mybatis基础
Mybatis基础 1.课程介绍 2.为什么需要Mybatis 3.初识Mybatis 3.1.Mybatis是什么 3.1.1.什么是框架 3.1.2.什么叫数据库持久化 3.1.3.什么是ORM ...
- java web开发实训心得,【JavaWeb实训心得体会材料】
JavaWeb实训心得体会材料 <JavaWeb实训心得体会材料.doc>由会员分享,可免费在线阅读全文,更多与<JavaWeb实训心得体会材料>相关文档资源请在帮帮文库(ww ...
- [JavaWeb实训Day4]__jsoup爬虫(爬新闻页面)词云的生成( kumo库)
目录 一.本次实验分析过程 二.Jee连接MySQL数据库 三.异步传值及界面设计 四.jsoup爬虫爬取新闻网页 五.新闻词云的生成( kumo库) 六.存入数据库 快速链接:[JavaWeb项目实 ...
- JavaWeb实训项目:基于SSM框架的CRM客户关系管理系统(文章最后有源码)
JavaWeb实训项目:基于SSM框架的CRM客户关系管理系统(附部分源码) 一.项目背景 项目演示 二.项目介绍 三.涉及技术 总结 源码地址 一.项目背景 "世上本来没有CRM,大家的生 ...
- [JavaWeb实训Day3]__button_框架布局点击事件
目录 一.基于JavaScript框架布局 二.button设置id 样式 三.button点击事件 快速链接:[JavaWeb项目实训]--总目录 我的运行环境在前面博客提到过,这里是在wc1项目下 ...
- JavaWeb实训项目 河南省旅游指南
1 基本信息 1.1 系统名称 河南省旅游指南的设计与实现 1.2 开发运行环境 Window 10 64位 JDK 1.8.0 IDEA 2019版本 MySql 5.1.47 Tomcat 8.5 ...
- javaweb实训第四天上午——员工管理系统-JavaBeanELJSTLMVC思想
目录 1.课程介绍 2.项目需求分析 3.JavaBean 3.1.什么是JavaBean 3.2.JavaBean的规范 3.3.Bean属性与对象属性 3.4.BeanUtils的使用(主要进行属 ...
- javaweb实训第三天上午——Servlet
文章目录 Servlet基础 1.Servlet基础 1.1.什么是Servlet 1.2.如何开发一个Servlet 1.3.Servlet执行流程 1.4.Servlet生命周期 1.5.Serv ...
- javaweb实训第五天上午——Spring基础
Spring基础 1.课程介绍 2.为什么需要Spring 3.初识Spring 3.1.什么是Spring 3.2.Spring框架的好处 3.3.Spring框架的模块化 4.Spring入门 4 ...
最新文章
- 软件版本命名规范(转载)
- 北斗导航 | 卫星导航基础知识(坐标系)
- 关于DubboMain启动的真相
- BGP小实验(二)——还是他,继续第二波走起来
- matplotlib可视化_使用Matplotlib改善可视化设计的5个魔术技巧
- python 打印皮卡丘_用python打印你的宠物小精灵吧
- php 数组随机排序_php 数组元素随机排序代码
- 大数据学习笔记06:伪分布式Hadoop
- java获取服务端mask_Java代码获取服务器所装office版本
- 最新网卡驱动下载win7
- QT模拟鼠标自动点击:1-鼠标移动自动显示坐标
- echolife hg8245说明书_华为光猫HG8245设置说明书
- AdventureWorks2008 数据库安装
- java 中文星期表示_java之获得中文星期几
- Windbg命令学习1(vertarget和lm和lmvm)
- python 音频文件 转列表 比对相似度
- OpenCV——图像窗口namedWindow
- 【随笔】记录一次简易的液位报警器的拆机修理
- 达人评测 i5 1155G7和i5 1135G7的差距大不大
- MNIST数据集的gist特征提取(含全部实例代码下载地址)
热门文章
- C++11 多线程线程共享数据
- window 创建python虚拟环境
- Flutter代码锦囊---切换时页面保持状态
- 中国内脏痛行业市场供需与战略研究报告
- 2021年中国等温核酸扩增技术市场趋势报告、技术动态创新及2027年市场预测
- SVN下载,安装,配置,常用操作 svn教程
- 文件上传学习:(结合upload-labs 01-12):part01
- SQL注入学习part01:(结合sqli-libs学习:1-10关)
- 为什么技术人干得越久越拿不到高薪?
- 华大基因辟谣“基因编辑58个婴儿”;苹果发布头戴式耳机AirPods Max;Debian 10.7发布|极客头条...