一. JSON
1.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}
-
1.2 JSON语法
//简单对象
var obj1 = {"name":"tom","age":34};
//复杂对象
var obj2 = {"name":"vikey","address":{"city":"成都","street":"九眼桥","room":"215"}};
//数组
var obj3 = [value,value,value]
//字符串
var obj4 = ‘{“id”:1,”name”:”tom”,”salary”:5000.0}’;
二. SpringMVC返回JSON
2.1 项目搭建
2.1.1 导入jar包
-
JSON
jackson-annotations-2.5.0.jar
jackson-core-2.5.0.jar
jackson-databind-2.5.0.jar
-
SpringMVC
spring-aop-4.1.2.RELEASE.jar
spring-beans-4.1.2.RELEASE.jar
spring-context-4.1.2.RELEASE.jar
spring-core-4.1.2.RELEASE.jar
spring-expression-4.1.2.RELEASE.jar
spring-test-4.1.2.RELEASE.jar
spring-web-4.1.2.RELEASE.jar
spring-webmvc-4.1.2.RELEASE.jar
-
日志log
commons-logging-1.1.1.jar
2.1.2 配置文件
-
新建一个source floder
-
spring-mvc.xml
-
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-- SpringMvc映射 --> <mvc:default-servlet-handler/> <!-- 指定扫描路径 --> <context:component-scan base-package="cn.xxxx"/> <!-- 启用spring-mvc的注解支持功能 --> <mvc:annotation-driven /> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property><!-- 前缀prefix:会自动在返回值前面加个上/ --> <property name="suffix" value=".jsp"></property><!--后缀suffix:会自动在返回值后面加个上.jsp --> </bean> </beans>
-
-
web.xml
-
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>day39_json_springmvc</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- *.xx注释范围太窄 --> <!-- <url-pattern>*.do</url-pattern> --> <!-- /* 什么都拦截,拦截范围太大,会拦截jsp --> <!-- <url-pattern>/*</url-pattern> --> <!-- / 不拦截jsp其他都会匹配,会拦截静态资源文件,js css 图片 --> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>characterEncoding</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>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2.2 代码实现
-
新建一个Employee类,其中有name,age,date字段
-
package cn.xxxx._01json; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import com.fasterxml.jackson.annotation.JsonFormat; public class Employee { private String name; private Integer age; private Date date; public Employee(String name, Integer age, Date date) { super(); this.name = name; this.age = age; this.date = date; } public Employee() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } //配置获取到的时间格式 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") public Date getDate() { return date; } //设置传入的时间格式 @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") public void setDate(Date date) { this.date = date; } @Override public String toString() { return "Employee [name=" + name + ", age=" + age + ", date=" + date + "]"; } }
-
进行代码测试
-
@ResponseBody
:将格式转换为JSON类型 -
import java.util.Arrays; import java.util.Date; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/json") public class JsonController { @RequestMapping("/get3") public Employee get(){ Employee employee = new Employee("VOGE3000", 2, new Date()); return employee; } @RequestMapping("/get") public String get2(){ return "1234321"; } @RequestMapping("/get2") @ResponseBody public List<Employee> get3(){ return Arrays.asList( new Employee("VOGE3000", 2, new Date()), new Employee("S1000RR", 2, new Date()), new Employee("TRK-502", 2, new Date()) ); } @RequestMapping("/set") @ResponseBody public void set(Employee employee){ System.out.println(employee.getDate()); } }
- 开启服务器,通过localhost/json/get可以获取到数据,但是我们传入/获取的date参数返回的是一个时间戳,要怎么进行格式化处理呢?
-
2.3 JSON中对日期格式的特殊处理
-
@JsonFormat
页面显示时间格式 -
@DateTimeFormat
设置时间格式 -
只需要在对应的读写属性上添加注解即可
-
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8") public Date getDate() { return date; } @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") public void setDate(Date date) { this.date = date; }
三. 实现文件的上传与下载
3.1 文件上传
-
文件上传三要素
- 表单的提交的方式必须是POST请求(get请求对提交的数据)
- 表单中必须有一个文件上传项:,文件上传项必须有name属性和值;
- 表单的enctype属性的值必须是multipart/form-data
-
需要添加的jar包:
- com.springsource.org.apache.commons.fileupload-1.2.0.jar
- com.springsource.org.apache.commons.io-1.4.0.jar
-
基本jsp页面
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="/file/upload" method="post" enctype="multipart/form-data"> name:<input type="text" name="name"> <br> file:<input type="file" name="mFile"> <br> <input type="submit" value="upload"> </form> </body> </html>
-
在
spirng-mvc.xml
中配置上传解析器 -
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置上传文件的最大尺寸为1MB --> <property name="maxUploadSize"> <!-- spring el写法:1MB --> <value>#{1024*1024}</value> </property> </bean>
-
后台代码实现
-
package cn.xxxx._02upload; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; @Controller @RequestMapping("/file") public class FileUpload { @RequestMapping("/upload") public void upload(MultipartFile mFile ,String name,HttpServletRequest req) throws Exception{ System.out.println("普通表单获取方式:" + name); System.out.println(mFile); //上传表单信息:注意MultipartFile对象的名称必须与上传表单项的name属性值一致 System.out.println("上传文件是否为空:" + mFile.isEmpty()); System.out.println("上传文件的大小(字节):" + mFile.getSize()); System.out.println("上传文件的类型:" + mFile.getContentType()); System.out.println("上传表单name属性值:" + mFile.getName()); System.out.println("上传文件名:" + mFile.getOriginalFilename()); //获取到原来的文件名 String filename = mFile.getOriginalFilename(); //获取到文件的真实路径 String realPath = req.getServletContext().getRealPath("/img"); //判断是否存在文件夹,不存在则创建 File parent = new File(realPath); if (!parent.exists()) { parent.mkdirs(); } filename = UUID.randomUUID().toString().replace("-", "")+"_"+filename; File file = new File(parent, filename); InputStream input = mFile.getInputStream(); FileOutputStream output = new FileOutputStream(file); IOUtils.copy(input, output); output.close(); input.close(); } }
3.2 文件下载
-
准备前端jsp页面
-
<%@page import="java.net.URLEncoder"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <ul> <li><a href="/file/download?filename=1.jpg">1.jpg</a></li> <!-- 设置浏览器解析编码,如果文件名含有中文,IE会出现访问错误的问题 --> <li><a href="/file/download?filename=<%=URLEncoder.encode("美女.jpg", "utf-8") %>">美女.jpg</a></li> <li><a href="/file/download?filename=yamazaki.mp4">yamazaki.mp4</a></li> <li><a href="/file/download?filename=<%=URLEncoder.encode("大桥.zip", "utf-8") %>">大桥.zip</a></li> </ul> </body> </html>
-
后台代码
-
import java.io.FileNotFoundException; import java.net.URLEncoder; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/file") public class DownloadController { @RequestMapping("/download") public void download(HttpServletRequest req, HttpServletResponse resp,String filename) throws Exception{ //获取文件路径 String realPath = req.getServletContext().getRealPath("/img") + "/" +filename; //设置输入流 FileInputStream fis = new FileInputStream(realPath); //判断是否为IE浏览器 ie浏览器使用UTF-8解析,其他浏览器使用ISO-8859-1进行解析 if (req.getHeader("User-Agent").toUpperCase().indexOf("TRIDENT")!= -1) { filename = URLEncoder.encode(filename,"UTF-8"); }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"); } //设置请求头,设置为下载内容 resp.setHeader("Content-Disposition", "attachment; filename=" + filename); //获取输出流 ServletOutputStream out = resp.getOutputStream(); IOUtils.copy(fis, out); fis.close(); out.close(); } }
-
注意点:
- 判断是否为IE浏览器,因为IE浏览器和其他浏览器的编码方式不相同,需要使用不同的方法进行解析
- 需要设置请求头,让浏览器识别这是一个下载的附件
- 解决中文名的文件问题,设置编码格式
四. SpringMVC拦截器
-
我们先创建一个拦截器,SpringMVC中已经写好了接口,我们只需要实现这个接口即可
-
package cn.xxxx._04Intercepter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class MyInercepter implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("1.拦截器开始拦截"); return true; } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("3.controller处理完毕后执行"); } @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("4.返回前端之前进行处理"); } }
-
测试拦截器
-
package cn.xxxx._04Intercepter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/inter") public class TestInercepter { @RequestMapping("/add") public void add(){ System.out.println("2.controller执行"); } }
-
这样我们在访问localhost/inter/add时通过控制台打印的信息即可知道拦截器是否成功执行