SpringMVC
1.MVC架构
- MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范
- 是将业务逻辑、数据、显示分离的方法来写代码
- MVC主要作用是:降低了视图和业务逻辑之间的双向耦合
- MVC是一个架构模型,不是一种设计模式。
1.model(模型)
数据模型,提供要展示的数据,因此包括数据和业务。
- 业务逻辑
- 保存数据的状态
2.view(视图)
负责进行模型的展示,一般就是界面,客户可以看到的东西
职责:
- 展示数据
3.controller(控制器)
接收用户的请求,委托给模型进行处理(状态改变),处理完之后再把返回的模型数据返回给视图,由视图负责展示。控制器相当于一个调度员。
职责:
- 取得表单的数据
- 调用业务逻辑
- 转向指定页面
最经典的MVC就是:servlet+jsp+javabean的模式
分为model1时代和model2时代:
model1:早期开发使用的是model1 只有视图层跟模型层,jsp职责不单一
model2:分为视图层,模型层,控制层
4.MVC架构需要做的事情
- 将url映射到java类或java类的方法
- 封装用户提交的数据
- 处理请求–>调用相关的业务处理—>封装响应数据
- 将响应的数据进行渲染,.jsp/html等表示层数据
2.什么是SpringMVC
Spring MVC是Spring Framework 的一部分 ,是基于Java实现MVC的轻量级Web框架
官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html
1.SpringMVC的优点:
- 轻量级,简单易学
- 高效,基于请响应的mvc框架
- 与spring兼容性好
- 约定优于配置
- 功能强大:restful 、数据验证、格式化、本地化、主题等
- 简洁灵活
2.SpringMVC的设计思想:
Spring的web框架是围绕DispatcherServlet【调度Servlet】设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始使用Java 5以上的版本的用户可以采用基于注解形式进行开发。
3.中心控制器
Spring的web框架是围绕DispatcherServlet【调度Servlet】设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring2.5开始使用Java 5以上的版本的用户可以采用基于注解形式进行开发。
SpringMVC框架像许多的其他mvc框架一样,以请求为驱动,围绕一个中心Servlet分派请求及提供其他功能,
DispatcherServlet是一个实际的Servlet
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FAVRHy7b-1616511435139)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223165929873.png)]
SpringMVC原理:
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用 模型与视图渲染视图结果,将结果返回给中心控制器,在将结果返回给请求者。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QeEYrYAI-1616511435143)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223171627039.png)]
3.SpringMVC的执行原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9S8ziqqL-1616511435144)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201223181703058.png)]
图为一个较为完整的SpringMVC流程图,实现表示SpringMVC框架提供的技术,不需要开发者实现,许仙表示需要开发者实现
简要的分析一下执行流程:
1.DispatcherServlet是一个前置控制器,是整个SpringMVC的控制中心。用户发送请求,DispatcherServlet接收并且拦截。
假设请求的url为:http://localhost:8080/SpringMVC/hello
将url拆分为三部分:
- 服务器域名 http://localhost:8080
- 部署在服务器的web站点 SpringMVC
- 控制器 hello
分析url可知:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器去
2.HandlerMapping为处理器映射,DispatcherServlet调用HandlerMapping,HandlerMapping根据url查找Handler
3.HandlerExecution表示具体的Handler,主要的工作是根据url查找控制器。如以上的url被查找的控制器为hello。
4.HandlerExecution将解析后的信息传递给DispatcherServlet
5.HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
6.Handler让具体的Controller执行
7.Controller将具体的执行信息返回给HandlerAdapter 如ModelAndView
8.HandlerAdapter 将视图模型或者逻辑名传递给DispatcherServlet
9.DispatcherServlet调用视图解析器来解析HandlerAdapter传递的逻辑试图名
10.视图解析器将解析的逻辑视图名传给DispatcherServlet
11.DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图
12.最终将试图传递给用户
4.helloSpringMVC
实现步骤:
- 新建一个web项目
- 导入相关的jar包
- 编写web.xml注册DispatcherServlet
- 编写Springmvc配置文件:处理器映射器、适配器
- 创建对应的控制类Controller
- 完成前端视图跟controller之间的对应
- 启动测试运行
使用SpringMVC必须配置的三大件:
处理器映射器、处理器适配器、视图解析器
通常只需手动配置视图解析器,其他两个只需要注解就可以实现。
1.配置版
1.新建一个web项目
2.导入相关依赖
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
3.配置web.xml 注册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">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定spring配置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.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>
</web-app>
4.创建springmvc配置文件: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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
5.配置处理器映射器
<!--添加处理映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
6.配置处理器适配器
<!--添加处理适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
7.配置视图解析器
<!--添加视图解析器-->
<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
8.编写controller实现Controller接口
package com.mahui.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
//ModelAndView 模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中。Model
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
return mv;
}
}
9.将自己的类交给SpringIOC容器注册bean
<!--注册controller-->
<bean id="/hello" class="com.mahui.controller.HelloController"/>
10.编写前端交互页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
11.配置tomcat运行测试。
2.注解版
1.新建一个web
2.由于maven有资源过滤问题,所以将配置完善
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
3.导入相关依赖
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
4.配置web.xml 注册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">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--绑定spring配置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.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>
</web-app>
5.添加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
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">
<!--开启扫描包-->
<context:component-scan base-package="com.mahui.controller"/>
<!--让spring不去处理静态的资源-->
<mvc:default-servlet-handler/>
<!--开启注解支持-->
<mvc:annotation-driven/>
<!--注册视图解析-->
<bean id="InternalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
6.创建controller
package com.mahui.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MyController {
//访问的地址 http://localhost:8080/h1
@RequestMapping("/h1")
public String test(Model model){
//业务处理像模型中添加msg可以在页面中取出并且渲染
model.addAttribute("msg","hello spring mvc annotation");
//试图跳转 /WEB-INF/jsp/hello.jsp
return "hello";
}
}
7.创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
8.配置tomcat启动测试
3.遇到的问题
遇到404页面,排查的步骤:
-
查看控制台输出,看一下是否缺少什么jar
-
如果jar包存在,显示无法输出,在idea项目发布中,添加lib目录,导入依赖
-
重新启动tomcat测试
5.RestFul风格
1.什么是RestFul?
RestFul就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这种风格设计的软件可以更加简洁,更加有层次,更易于实现缓存等机制。4
资源:互联网所有的事物都可以被抽象为资源
学习测试:
在springmvc中可以使用@PathVariable 注解,让方法参数的值对应绑定到一个URL模板变量上
//http://localhost:8080/t2?a=1&b=2 传统的
//http://localhost:8080/t2/1/3 RestFul风格
@RequestMapping("/t2/{a}/{b}")
public String test02( @PathVariable int a, @PathVariable int b, Model model){
int msg= a+b;
model.addAttribute("msg",msg);
return "hello";
}
优点:
- 使路径变得更加简洁
- 获取参数更加方便,框架会自动进行类型转换
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法。
使用method属性指定请求类型:
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型为GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE,TRACE等
测试:
@RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.POST)
public String test02( @PathVariable int a, @PathVariable int b, Model model){
int msg= a+b;
model.addAttribute("msg",msg);
return "hello";
}
浏览器地址栏进行访问默认是GET请求,会报错405
将post修改为get即可
//http://localhost:8080/t2/1/3 RestFul风格
@RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.GET)
public String test02( @PathVariable int a, @PathVariable int b, Model model){
int msg= a+b;
model.addAttribute("msg",msg);
return "hello";
}
不同的请求方式对应的注解:
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
@PatchMapping
//简化了@RequestMapping(value = "/t2/{a}/{b}",method = RequestMethod.GET)
6.重定向与转发
1.ModelAndView
public class ModelAndViewController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
//返回一个模型视图对象
mv.addObject("msg","ModelAndViewController");
mv.setViewName("test");
return mv;
}
}
springmvc-servlet.xml
<!--注册ModelAndViewController-->
<bean id="/test" class="com.mahui.controller.ModelAndViewController"/>
测试路径:http://localhost:8080/test
2.servletApi
通过设置ServletAPI,不需要视图解析器。将视图解析器注掉
- 通过HttpServletResponse进行输出
- 通过HttpServletResponse实现重定向
- 通过HttpServletRequest实现转发
@Controller
public class ServletAPIController {
@RequestMapping("/result/t1")
public void test1(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("通过HttpServletResponse进行输出");
}
@RequestMapping("/result/t2")
public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect("/index.jsp");
}
@RequestMapping("/result/t3")
public void test3(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("msg","通过HttpServletRequest实现转发");
request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request,response);
}
}
3.SpringMVC
通过SpringMVC实现试图转发和重定向,同样也不需要视图转发
测试前将视图解析器注掉
@Controller
public class SpringMVCController {
@RequestMapping("/smv/t1")
public String test1(){
//转发方式一
return "/spring01.jsp";
}
@RequestMapping("/smv/t2")
public String test2(){
//转发方式二
return "forward:/spring02.jsp";
}
@RequestMapping("/smv/t3")
public String test3(){
//重定向
return "redirect:/spring03.jsp";
}
}
7.接收请求参数及数据回显
1.处理提交数据
1.提交的域名称和处理方法的参数名一致
提交的数据:http://localhost:8080/hello1?name=zhangsan
@RequestMapping("/hello1")
public String test1(String name){
//http://localhost:8080/hello1?name=zhangsan
System.out.println(name);
return "hello";
}
2.提交的域名和处理方法的参数名不一致
提交的数据:http://localhost:8080/hello2?username=zhangsan
需要使用注解:@RequestParam(“username”)
@RequestMapping("/hello2")
public String test2(@RequestParam("username") String name){
//http://localhost:8080/hello2?username=zhangsan
System.out.println(name);
return "hello";
}
2.数据显示到前端
1.通过ModelAndView
public class ModelAndViewController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
//返回一个模型视图对象
mv.addObject("msg","ModelAndViewController");
mv.setViewName("test");
return mv;
}
}
2.通过ModelMap
@Controller
public class MyController03 {
@RequestMapping("hello/test1")
public String test1(ModelMap modelMap){
//封装要显示的数据
modelMap.addAttribute("msg","ModelMap");
return "hello";
}
3.通过Model
@RequestMapping("hello/test2")
public String test2(Model model){
//封装要显示的数据
model.addAttribute("msg","Model");
return "hello";
}
3.提交的是一个对象
提交的数据:http://localhost:8080/hello3?id=1&name=zhangsan&age=66
实体类:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int id;
private String name;
private int age;
}
测试:
@RequestMapping("/hello3")
public String test3(User user){
//http://localhost:8080/hello3?id=1&name=zhangsan&age=66
System.out.println(user);
return "hello";
}
注意的是:如果使用对象,前端传来的参数名和对象名必须一致,否则就是null
8.乱码解决问题
前端表单:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/e/t1" method="post">
<input type="text" name="name"><br/>
<input type="submit">
</form>
</body>
</html>
测试:
@Controller
public class MyController04 {
@RequestMapping("/e/t1")
public String test1(HttpServletRequest request, HttpServletResponse response, Model model){
//接收前端参数
String name = request.getParameter("name");
System.out.println(name);
//返回前端参数
model.addAttribute("msg",name);
return "hello";
}
}
测试结果:
网页乱码:
控制台乱码:
1.使用SpringMVC过滤器
web.xml中配置
<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>
2.自己写过滤器
public class CharacterEncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
web中配置
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.mahui.Filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.使用大神写的
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;
}
}
在web.xml中进行配置
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.mahui.Filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4修改Tomcat的配置文件
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
5./和/*的区别
- / 请求的不包括jsp文件
- /*请求包括所有的包括jsp文件
9.JSON
1.什么是json
- JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式
- 采用完全独立于编程语言的文本格式来存储和表示数据
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
js对象格式:
{name: "张三", age: 18, sex: "男"}
json字符串格式:
{"name":"张三","age":18,"sex":"男"}
将js对象转换为json字符串使用JSON.stringify()方法
//将对象转为json字符串
var objectjson=JSON.stringify({a:"Hello",b:"Json"});
将json字符串转换为js对象使用JSON.parse()方法
//将json字符串转换为对象
var jsonobject=JSON.parse('{"a":"Hello","b":"Json"}');
测试:
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/12/25 0025
Time: 9:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<script type="text/javascript">
var user={
name:"张三",
age:18,
sex:"男"
}
//控制台打印user对象
console.log(user)
//将js对象转换为JSon字符串
var str=JSON.stringify(user);
console.log(str);
//将JSON字符串转为js对象
var user1=JSON.parse(str);
console.log(user1)
//这是一个对象键值对存在的
var object={a:"Hello",b:"Json"};
console.log(object)
//这是一个JSON字符串,本质是一个字符串
var json='{"a":"Hello","b":"Json"}';
console.log(json)
//将对象转为json字符串
var objectjson=JSON.stringify({a:"Hello",b:"Json"});
console.log(objectjson)
//将json字符串转换为对象
var jsonobject=JSON.parse('{"a":"Hello","b":"Json"}');
console.log(jsonobject)
</script>
</body>
</html>
2.Jackson使用
jackson是json的解析工具
1.导入jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.0</version>
</dependency>
2.将对象转为json字符串
@Controller
public class Test {
@RequestMapping("/json1")
@ResponseBody//不走视图解析器
public String jsontest() {
//创建一个jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建对象
User user = new User("张三", 12, "男");
//将对象解析为json格式
//由于注解@`` ` ` ResponseBody这里会将str转换为json格式返回
String string = null;
try {
string = mapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return string;
}
}
3.将日期转为json字符串
@Controller
public class Test {
@RequestMapping("/json1")
@ResponseBody//不走视图解析器
public String jsontest() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mapper.setDateFormat(format);
Date date = new Date();
//User user = new User("张三", 12, "男");
String string = null;
try {
string = mapper.writeValueAsString(date);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return string;
}
}
3.将其写为工具类JsonUtils
JsonUtil.java:工具类中使用方法的重载,里面的业务需求不需要在写直接调用,给不需要的传递的参数传为null即可
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
public class JsonUtil {
public static String getjson(Object o) {
String string = getjson(o, null);
return string;
}
public static String getjson(Object o, SimpleDateFormat format) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(format);
String string=null;
try {
string = mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return string;
}
}
测试:
import com.mahui.pojo.User;
import com.mahui.utils.JsonUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class Test2 {
@RequestMapping("/json2")
@ResponseBody
public String test1(){
User user = new User("李四", 15, "女");
String string = JsonUtil.getjson(user);
System.out.println(string);
return string;
}
@RequestMapping("/json3")
@ResponseBody
public String test2(){
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String string = JsonUtil.getjson(date, format);
return string;
}
}
3.Fastjson使用
1.导入jar包
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
2.测试:
import com.alibaba.fastjson.JSON;
import com.mahui.pojo.User;
import java.util.ArrayList;
public class FastJsonTest {
public static void main(String[] args) {
User user1 = new User("张三1", 45, "男");
User user2 = new User("张三2", 45, "男");
User user3 = new User("张三3", 45, "男");
User user4 = new User("张三4", 45, "男");
User user5 = new User("张三5", 45, "男");
ArrayList<User> userlist = new ArrayList<User>();
userlist.add(user1);
userlist.add(user2);
userlist.add(user3);
userlist.add(user4);
userlist.add(user5);
String string = JSON.toJSONString(userlist);
System.out.println(string);
}
}
10.拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。
**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。
过滤器
- servlet规范中的一部分,任何java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
如何实现拦截器?
想要自定义拦截器,必须实现 HandlerInterceptor 接口。
11.登陆判断验证
拦截用户的请求,判断用户是否登陆。如果用户登陆。放行,如果用户未登陆,跳转到登陆页面。
-
编写一个登陆页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1> <form action="${pageContext.request.contextPath}/user/login" method="post"> 用户名: <input type="text" name="username"/><br> 密码: <input type="password" name="password"/> <input type="submit" name="提交"/> </form> </h1> </body> </html>
-
编写一个Controller请求
package com.mahui.Controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpSession; @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/goLogin") public String goLogin(){ return "login"; } @RequestMapping("/main") public String main(){ return "main"; } @RequestMapping("/login") public String login(String username, String password, HttpSession session){ //将用户信息记录在session中 session.setAttribute("userInfo",username); return "main"; } @RequestMapping("/loginOut") public String loginOut( HttpSession session){ //session过期 session.invalidate(); return "login"; } }
-
编写主页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>首页</h1> <a href="${pageContext.request.contextPath}/user/loginOut">退出登录</a> </body> </html>
-
在index页面上跳转
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <h1> <a href="${pageContext.request.contextPath}/user/goLogin">登录页面</a> </h1> <h1> <a href="${pageContext.request.contextPath}/user/main">首页</a> </h1> </body> </html>
-
编写用户拦截器
package com.mahui.config; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class UserInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); //如果是登陆页面放行 if(request.getRequestURI().contains("login")){ return true; } //如果用户已经登陆放行 if(session.getAttribute("userInfo")!=null){ return true; } request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response); return false; } }
-
配置用户拦截器
<mvc:interceptor> <!--包括这个请求下的所有请求--> <mvc:mapping path="/user/**"/> <bean class="com.mahui.config.UserInterceptor"/> </mvc:interceptor>
-
启动tomcat进行测试