文章目录
SpringMVC
- MVC是模型(model)、视图(view)、控制器(Controller)的简写,是一种软件设计规范。
- 是将业务逻辑、数据、显示分离的方式来组织代码。
- MVC的作用是降低了视图与业务逻辑间的双向耦合。
- MVC不是一种设计模式,MVC是一种架构模式。
1、回顾Servlet
-
创建springmvc普通的Maven项目;
-
添加Framework Support
-
创建HelloServlet
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1、获取前端参数 String method = req.getParameter("method"); if (method.equals("add")) { req.getSession().setAttribute("msg","执行了add方法。"); } if (method.equals("delete")) { req.getSession().setAttribute("msg","执行了delete方法。"); } //2、调用业务层 //3、视图转发或者重定向 req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
创建test.jsp
<form action="/hello" method="get"> <input type="text" name="method"/> <input type="submit"> <h1>Test:${msg}</h1> </form>
-
添加Tomcat支持,并启动测试http://localhost:8080/hello?method=add
2、第一个SpringMVC
-
配置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"> <!-- 1、注册DispatcherServlet --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 关联一个springmvc的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-config.xml</param-value> </init-param> <!-- 启动级别、1 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
在resources目录下编写springmvc-config.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean> <bean id="/hello" class="com.ls.controller.HelloController"/> </beans>
-
编写HelloController
public class HelloController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //ModelAndView 视图和模型 ModelAndView view = new ModelAndView(); //封装对象,放在ModelAndView中 view.addObject("msg", "Hello SpringMVC"); //封装要跳转的视图,放在ModelAndView中 view.setViewName("hello"); return view; } }
-
启动Tomcat测试
如果遇到404的情况:
3、理解SpringMVC执行流程(重点)
[https://www.bilibili.com/video/BV1aE41167Tu?p=5]
- 确定导入spring-webmvc依赖
- 确定最后发的项目中Artifacts中也有相应的Jar包
-
配置DIspatcherServlet(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"> <!-- 配置DispatchServlet:这个是SpringMVC的核心;请求分发器;前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- DispatcherServlet要绑定Spring的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 启动级别、1 --><!-- 让他跟服务器一块启动 --> <load-on-startup>1</load-on-startup> </servlet> <!-- SpringMVC中:/ 和 /* 的区别 /:只匹配所有的请求,不会去匹配jsp页面 /*:只匹配所有的请求,包括jsp页面 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
配置Spring的配置文件(springmvc-servlet.xml)(以下三个是SpringMVC的核心三要素)
-
处理器映射器
<!-- 处理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
-
处理器适配器
<!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
-
视图解析器
<!-- 视图解析器 模板引擎:Thymeleaf Freemarker--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean>
-
-
编写控制层
public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result = "HelloSpringMVC"; mv.addObject("msg", result); //视图跳转 mv.setViewName("test"); return mv; } }
-
由于使用了BeanNameUrlHandlerMapping映射器,所以需要注册Bean
<bean id="/hello" class="com.ls.controller.HelloController"/>
-
确定test.jsp可以收到msg
${msg}
4、注解开发
-
配置DispatcherServlet
<?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"> <!-- 配置DispatchServlet:这个是SpringMVC的核心;请求分发器;前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- DispatcherServlet要绑定Spring的配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!-- 启动级别、1 --><!-- 让他跟服务器一块启动 --> <load-on-startup>1</load-on-startup> </servlet> <!-- SpringMVC中:/ 和 /* 的区别 /:只匹配所有的请求,不会去匹配jsp页面 /*:只匹配所有的请求,包括jsp页面 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-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 https://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 http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自动扫描包,让指定包下的注解生效 --> <context:component-scan base-package="com.ls.controller"/> <!-- 默认的资源过滤,让SpringMVC不在处理静态资源 .css/.js/.mp3等 --> <mvc:default-servlet-handler/> <!--支持mvc注解驱动 --> <mvc:annotation-driven/> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀(在视图解析其中,把所有的视图都存放在WEB-INF下,这样可以保证视图安全,因为客户端不能直接访问这个目录下的文件。) --> <property name="prefix" value="WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean> </beans>
-
创建Controller
@Controller//自动被Spring扫描到 public class HelloController { @RequestMapping("/hello") public String hello(Model model) { model.addAttribute("msg", "HelloSpringmvc......"); return "hello"; } }
-
在hello.jsp中用${msg}取出信息。
-
如果出现404,检查WEB-INF下是否创建lib目录,并把相关jar包导入。
使用SpringMVC必须配置的三大件:处理器映射器,处理器适配器,视图解析器
5、控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
6、实现Controller
第一种Controller实现方式,实现Controller接口:
-
public class ControllerTest1 implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView view = new ModelAndView(); view.addObject("msg", "ControllerTest1"); view.setViewName("test1"); return view; } }
-
在spring配置文件中注册Controller Test1
<bean name="/t1" class="com.ls.controller.ControllerTest1"/>
注意:实现Controller接口定义控制器是比较老的办法;
缺点是一个控制器只可以实现一个方法,如果需要多个方法则需要定义多个控制器,定义的方式比较麻烦。
第二种实现Controller方式是使用注解
@Controller注解类型用于声明Spring类的实例是一个容器
@Controller// 代表这个类会被Spring自动接管
//在这个类中的所有方法,如果返回值是String,并且有具体页面可以跳转,那么就会被视图解析器解析。
public class ControllerTest2 {
@RequestMapping("/t2")
public String test1(Model model) {
model.addAttribute("msg", "ControllerTest2...");
return "test1";//WEB-INF/jsp/test1.jsp
}
}
开启包扫描
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.ls.controller"/>
7、RequestMapping
@RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或者方法上。用于类上,表示类中的所有相应请求的的方法都已该地址作为父路径。
@Controller
@RequestMapping("/father")
public class ControllerTest3 {
@RequestMapping("/test1")
public String test1(Model model) {
model.addAttribute("msg", "Controller中的test1()......");
return "test1";
}
}
访问路径:localhost:8080/father/test1
8、RestFul风格
以前的访问地址例如:localhost:8080/login?username=root&password=123
RestFul风格(以斜线分割):localhost:8080/login/username/root
RestFul就是一个资源定位即资源操作的风格。不是标准不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
@Controller
public class RestFulController {
//原来的方式:http://localhost:8080/add?a=1&b=2
@RequestMapping("/add")
public String test1(int a, int b, Model model) {
int result = a + b;
model.addAttribute("msg", "结果为" + result);
return "test1";
}
// RestFul风格:http://localhost:8080/sub/9/5
@RequestMapping("/sub/{a}/{b}")
public String test2(@PathVariable int a, @PathVariable String b, Model model) {
String result = a + b;
model.addAttribute("msg", "结果为" + result);
return "test1";
}
}
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
使用method属性指定请求类型
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
测试:增加一个方法
-
@RequestMapping(value = "/sub/{a}/{b}", method = RequestMethod.POST) public String test2(@PathVariable int a, @PathVariable int b, Model model) { int result = a - b; model.addAttribute("msg", "结果为" + result); return "test1"; }
-
使用浏览器地址栏访问默认是GET请求,会报错405。
-
将method改为GET就可以正常执行了。
@RequestMapping(value = "/sub/{a}/{b}", method = RequestMethod.GET) public String test2(@PathVariable int a, @PathVariable int b, Model model) { int result = a - b; model.addAttribute("msg", "结果为" + result); return "test1"; }
所有的地址栏请求默认都会是HTTP GET类型的。
方法级别的注解变体有如下几个:组合注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@GetMapping是一个组合注解,平时用的会比较多。
他所扮演的是@RequestMapping(method=RequestMethod.GET)的一个快捷方式。
总结:
- 最大的好处:安全,在地址栏上别人不知道你传参数的具体含义,隐藏了程序里的一些东西。
- 是路径变得更加简介;
- 获得参数更加方便,框架会自动进行类型转换;
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法。
9、重定向和转发
通过SpringMVC来实现重定向和转发-无需视图解析器
测试前,将视图解析器注释掉。
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test1(Model model) {
model.addAttribute("msg", "ModelTest1执行了");
//return "/WEB-INF/jsp/test1.jsp";//转发
return "forward:/WEB-INF/jsp/test1.jsp";//转发
}
@RequestMapping("/m1/t2")
public String test2(Model model) {
model.addAttribute("msg", "ModelTest1执行了");
return "redirect:/index.jsp";//重定向
}
}
通过SpringMVC来实现重定向和转发-有视图解析器
重定向,一个新的地方不需要视图解析器,本质就是重新请求,所以注意路径问题。
@Controller
public class ResultSpringMVC2 {
@RequestMapping("/rsm2/t1")
public String test1(){
//转发
return "test";
}
@RequestMapping("/rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
//return "redirect:hello.do"; //hello.do为另一个请求/
}
}
10、数据处理
处理提交数据
-
提交的域名称和处理方法的参数一致
提交数据:http://localhost:8080/hello?name=leishuai
@RequestMapping("/hello") public String hello(String name){ System.out.println(name); return "hello"; }
后台输出:leishuai
-
提交的域名称和处理方法的参数不一致
提交数据:http://localhost:8080/hello?username=leishuai
//从前端接收一个参数 @RequestMapping("/t1") public String test1(@RequestParam("username") String name, Model model) { System.out.println("从前端接收的参数:" + name); model.addAttribute("msg", name); return "test1"; }
-
提交一个对象
创建一个User对象
public class User { private int id; private String name; private int age; }
提交数据:http://localhost:8080/user/t2?id=1001&name=zhangsan&age=20
//从前端接收一个对象 @RequestMapping("/t2") public String test2(User user) { System.out.println(user); return "test1"; }
提交的表单数据需要和实体类的属性名一致,参数使用对象即可。
后台输出
User(id=1001, name=zhangsan, age=20)
如果提交的表单数据和实体类的属性不一致,就会出现null;
http://localhost:8080/user/t2?id=1001&username=zhangsan&age=20
User(id=1001, name=null, age=20)
11、数据显示到前端
第一种 : 通过ModelAndView
我们前面一直都是如此 . 就不过多解释
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
第二种 : 通过ModelMap
ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}
第三种 : 通过Model
Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
对比
就对于新手而言简单来说使用区别就是:
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
12、乱码问题
-
<form action="/e/t1" method="GET"> <input type="text" name="name"/> <input type="submit"> </form>
-
@Controller public class EncodingController { @RequestMapping("/e/t1") public String test1(String name, Model model) { System.out.println(name); model.addAttribute("msg", name); return "test1"; } }
解决办法:
- 在web.xml中配置SpringMVC的乱码过滤
<!--2、配置SpringMVC的乱码过滤-->
<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>
-
或者导入自定义的乱码过滤器
<!--自定义的乱码过滤器--> <filter> <filter-name>encoding</filter-name> <filter-class>com.ls.controller.GenericEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
GenericEncodingFilter
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; /** * 解决get和post请求 全部乱码的过滤器 */ public class GenericEncodingFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //处理response的字符编码 HttpServletResponse myResponse=(HttpServletResponse) response; myResponse.setContentType("text/html;charset=UTF-8"); // 转型为与协议相关对象 HttpServletRequest httpServletRequest = (HttpServletRequest) request; // 对request包装增强 HttpServletRequest myrequest = new MyRequest(httpServletRequest); chain.doFilter(myrequest, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { } } //自定义request对象,HttpServletRequest的包装类 class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; //是否编码的标记 private boolean hasEncode; //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰 public MyRequest(HttpServletRequest request) { super(request);// super必须写 this.request = request; } // 对需要增强方法 进行覆盖 @Override public Map getParameterMap() { // 先获得请求方式 String method = request.getMethod(); if (method.equalsIgnoreCase("post")) { // post请求 try { // 处理post乱码 request.setCharacterEncoding("utf-8"); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } else if (method.equalsIgnoreCase("get")) { // get请求 Map<String, String[]> parameterMap = request.getParameterMap(); if (!hasEncode) { // 确保get手动编码逻辑只运行一次 for (String parameterName : parameterMap.keySet()) { String[] values = parameterMap.get(parameterName); if (values != null) { for (int i = 0; i < values.length; i++) { try { // 处理get乱码 values[i] = new String(values[i] .getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } } hasEncode = true; } return parameterMap; } return super.getParameterMap(); } //取一个值 @Override public String getParameter(String name) { Map<String, String[]> parameterMap = getParameterMap(); String[] values = parameterMap.get(name); if (values == null) { return null; } return values[0]; // 取回参数的第一个值 } //取所有值 @Override public String[] getParameterValues(String name) { Map<String, String[]> parameterMap = getParameterMap(); String[] values = parameterMap.get(name); return values; } }
13、JSON
- json是一种轻量级的数据交换格式,目前使用特别广泛;
- 采用完全独立于编程语言的文本格式来存储和展示数据;
- 简洁和清晰的层次结构使得json成为理想的数据交换语言;
- 已于阅读和编写,同时也易于机器解析和生成,有效的提升网络传输效率。
<script>
//编写一个JavaScript对象 ES6
var user = {
name: "吕布",
age: 20,
sex: "男"
};
//将js对象转换为json对象
var json = JSON.stringify(user);
console.log(json);
console.log("-----------------")
//将json对象转化为js对象
var obj = JSON.parse(json);
console.log(obj);
</script>
13.1、JackSon
目前比较好的json解析工具
这里使用Jackson,需要导入它的jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
编写测试类:
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串
public String json1() throws JsonProcessingException {
//Jackson ,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("张三",20, "男");
String value = mapper.writeValueAsString(user);
return value;
}
}
输出发现乱码:
13.2、Json乱码解决办法
在web.xml中添加:
<!-- JSON乱码问题配置 -->
<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>
Json添加多个对象
@RequestMapping("/j2")
@ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串
public String json2() throws JsonProcessingException {
//Jackson ,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
List<User> userList = new ArrayList<>();
//创建多个对象
User user = 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(user);
userList.add(user2);
userList.add(user3);
userList.add(user4);
userList.add(user5);
String result = mapper.writeValueAsString(userList);
return result;
}
13.3、Json返回时间对象
@RequestMapping("/j3")
@ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串
public String json3() throws JsonProcessingException {
//Jackson ,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
String value = mapper.writeValueAsString(date);
return value;
}
时间解析后的默认格式为:时间戳:Timestamp( 时间戳是自1970 年 1 月 1 日(00:00:00 GMT)以来的秒数。它也被称为 Unix 时间戳(Unix Timestamp))。
时间格式化方式一:自定义时间戳
@RequestMapping("/j3")
@ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串
public String json3() throws JsonProcessingException {
//Jackson ,ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
//自定义日期的格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String value = mapper.writeValueAsString(dateFormat.format(date));//默认返回时间戳
return value;
}
时间格式化方式二:不使用时间戳
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
封装一个Json工具类
public class JsonUtils {
//方法重载
public static String getJson(Object object) throws JsonProcessingException {
return getJson(object, "yyyy-MM-dd hh:mm:ss");
}
//自定义时间戳
public static String getJson(Object object, String dataFormat) {
ObjectMapper mapper = new ObjectMapper();
SimpleDateFormat format = new SimpleDateFormat(dataFormat);
mapper.setDateFormat(format);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
//自定义JsonUtils转换时间戳
@RequestMapping("/j4")
@ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串
public String json4() throws JsonProcessingException {
Date date = new Date();
return JsonUtils.getJson(date, "yyyy-MM-dd HH:mm:ss");
}
13.4、FastJson
-
导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency>
-
测试
@RequestMapping("/j5") @ResponseBody//加了@ResponseBody就不会走视图解析器,会直接返回一个字符串 public String json5() throws JsonProcessingException { List<User> userList = new ArrayList<>(); //创建多个对象 User user = 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(user); userList.add(user2); userList.add(user3); userList.add(user4); userList.add(user5); return JSON.toJSONString(userList); }
14、Ajax
-
新建一个Module
-
添加web支持
-
配置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:applicationContext.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>
-
配置applicationContext.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="com.ls.controller"/> <!-- 开启注解支持 --> <mvc:annotation-driven/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <!--前缀--> <property name="prefix" value="/WEB-INF/jsp/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> </beans>
-
controller
@RestController//表示这整个类都不会走视图解析器 public class AjaxController { @RequestMapping("/t1") public String test() { return "hello"; } }
-
配置Tomcat服务器,部署项目。
- 测试一:
@RequestMapping("/t3")
public List<User> test3() {
List<User> userList = new ArrayList<>();
userList.add(new User("张三",10, "男"));
userList.add(new User("李四",10, "男"));
userList.add(new User("王五",10, "男"));
return userList;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax刷新</title>
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script>
$(function () {
$("#btn").click(function () {
$.post({
url:"/t3",
success: function (data) {
// console.log(data);
var html = "";
for (let i = 0; i < data.length; i++) {
html += "<tr>" +
"<td>" + data[i].name +"</td>"+
"<td>" + data[i].age +"</td>"+
"<td>" + data[i].sex +"</td>"
"</tr>";
}
$("#content").html(html);
}
})
})
});
</script>
</head>
<body>
<input type="button" value="提交数据" id="btn">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
</tr>
<tbody id="content">
<!-- 数据从后台来 -->
</tbody>
</table>
</body>
</html>
- 测试二:
@RequestMapping("/t4")
public String test4(String name, String pwd) {
String msg = "";
if (name != null) {
if ("admin".equals(name)){
msg = "OK";
} else {
msg = "名字不匹配";
}
}
if (pwd != null) {
if ("1234".equals(pwd)){
msg = "OK";
} else {
msg = "密码有误";
}
}
return msg;
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.min.js"></script>
<script>
function a() {
$.post({
url: "/t4",
data: {"name": $("#name").val()},
success: function (data) {
if (data.toString() == "OK") {
$("#userInfo").css("color","green");
} else {
$("#userInfo").css("color","red");
}
$("#userInfo").html(data);
}
});
}
function b() {
$.ajax({
url: "/t4",
data: {"pwd": $("#pwd").val()},
success: function (data) {
console.log(data);
if (data.toString() == "OK") {
$("#pwdInfo").css("color","green");
} else {
$("#pwdInfo").css("color","red");
}
$("#pwdInfo").html(data);
}
});
}
</script>
</head>
<body>
<p>
用户名:<input type="text" id="name" οnblur="a()"/>
<span id="userInfo"></span>
</p>
<p>
密码:<input type="text" id="pwd" οnblur="b()"/>
<span id="pwdInfo"></span>
</p>
</body>
</html>
15、SpringMVC拦截器
实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
//return true;执行下一个拦截器放行
//return false;不执行下一个拦截器
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("-------------处理之前----------------");
return false;
}
}
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.ls.config.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
测试:
@RestController
public class TestController {
@RequestMapping("/t1")
public String test1() {
System.out.println("test1执行了");
return "OK!";
}
}
结果:
return true:
16、文件上传
-
导入依赖
<dependencies> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies>
-
文件上传配置
<!-- 文件上传配置,id="multipartResolver"是固定的不能更改 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 请求的编码格式,必须和jsp的pageEncoding属性一致,以便正确的读取表单的内容,默认为ISO-8859-1 --> <property name="defaultEncoding" value="utf-8"/> <!-- 文件上传大小限制,单位字节(10485760=10M) --> <property name="maxUploadSize" value="10485760"/> <property name="maxInMemorySize" value="40960"/> </bean>
-
FileController
@RequestMapping("/upload") public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException { //获取文件名字 String uploadFileName = file.getOriginalFilename(); //如果文件名为空,直接返回首页 if ("".equals(uploadFileName)) { return "redirect:/index.jsp"; } System.out.println("上传文件名:" + uploadFileName); //上传路径保存设置 String path = request.getServletContext().getRealPath(("/upload")); //如果路径不存在,则创建一个 File realPath = new File(path); if (!realPath.exists()) { realPath.mkdir(); } System.out.println("上传文件保存地址:" + realPath); //文件输入流 InputStream is = file.getInputStream(); //文件输出流 OutputStream os = new FileOutputStream(new File(realPath, uploadFileName)); //读取写出 int len = 0; byte[] buffer = new byte[1024]; while ((len=is.read(buffer)) != -1) { os.write(buffer,0,len); os.flush(); } os.close(); is.close(); return "redirect:/index.jsp"; }
-
测试的jsp
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post"> <input type="file" name="file"/> <input type="submit" value="upload"> </form>
文件下载:
@RequestMapping("/download")
public String downloads(HttpServletResponse response, HttpServletRequest request) throws Exception {
//要下载的图片地址
String path = request.getServletContext().getRealPath("/static");
String fileName = "1.jpg";
//1、设置response响应头
response.reset();//设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8");//字符编码
response.setContentType("multipart/form-data");//二进制传输数据
//设置响应头
response.setHeader("Content-Disposition","attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path,fileName);
//2、读取文件--输入流
FileInputStream inputStream = new FileInputStream(file);
//3、写出文件--输出流
OutputStream outputStream = response.getOutputStream();
byte[] buff = new byte[1024];
int index = 0;
//4、执行 写出操作
while ((index = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, index);
outputStream.flush();
}
outputStream.close();
inputStream.close();
return "OK";
}