SSM_SpringMVC_Day01(Spring与web、简介、快速入门、数据响应、请求处理)
1. Spring与web
1.1. ApplicationContext应用上下文获取方式
应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。
在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。
1.2. Spring提供获取应用上下文的工具
上面的分析不用手动实现,Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。
所以我们需要做的只有两件事:
①在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)
②使用WebApplicationContextUtils获得应用上下文对象ApplicationContext
1.3.使用
1 使用maven创建一个web项目
引入所需的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.lanqiao</groupId>
<artifactId>web_01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>web_01 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.version>5.2.12.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<build>
<finalName>web_01</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<url>/</url>
</configuration>
</plugin>
</plugins>
</build>
</project>
在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">
<!-- 配置spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!--配置监听器 监听web应用的启动 在启动的时候 将ApplicationContext创建并保存在ServletContext对象中 一个web应用只有一个-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置一个基础的servlet -->
<servlet>
<servlet-name>web</servlet-name>
<servlet-class>cn.lanqiao.dao.WebServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>web</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring的配置
<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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="cn.lanqiao.dao"/>
</beans>
创建Servlet
public class WebServlet1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext sc;
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext());
UserDao dao = context.getBean(UserDao.class);
dao.save();
}
}
dao
@Repository
public class UserDao {
public void save(){
System.out.println("保存对象成功 " );
}
}
2. SpringMVC的简介
2.1. SpringMVC概述
SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。
SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。
3. SpringMVC快速入门
需求:客户端发起请求,服务器端接收请求,执行逻辑并进行视图跳转。
开发步骤
①导入SpringMVC相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
②配置springmvc的中央处理器
③创建Controller类和视图页面
④使用注解配置Controller类中业务方法的映射地址
@Controller//表明该类为一个处理器
public class HelloController {
@RequestMapping("/hello")//定义了该处理方法的 映射路径
public String hello(){
return "success";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
⑤配置SpringMVC核心文件 spring-mvc.xml
<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:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
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">
<!-- 配置springmvc扫描的基础包 -->
<context:component-scan base-package="cn.lanqiao.controller"/>
<!-- 配置试图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
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">
<!-- 配置spring的其余配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-*.xml</param-value>
</context-param>
<!-- springmvc的 中央处理器/中央调度器/前端处理器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- springmvc 配置文件的位置 -->
<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>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
⑥客户端发起请求测试
3.1.springmvc入门问题
1 tomcat插件启动失败
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<!-- scope 表示该依赖只在编译期有效-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
原因在于servlet-api和jsp-api 版本冲突,因此需要指定我们引入的依赖的使用范围
2 处理器处理成功之后 返回不到试图的问题
@Controller//
public class HelloController {
@RequestMapping("/hello")//
public String hello(){
System.out.println("helloController.....");
return "/WEB-INF/success.jsp";
}
}
如果返回的字符串是一个试图完整路径的时候 则不需要配置试图解析器
@Controller//
public class HelloController {
@RequestMapping("/hello")//
public String hello(){
System.out.println("helloController.....");
//此时为试图的完整路径 第一个/表示项目的web目录
//如果返回的只有试图名称 则需要配置试图解析器
return "success";
}
}
如果返回的只是一个试图名称 则需要配置试图解析器
3.2.SpringMVC的处理流程
3.3. SpringMVC的组件解析
3.3.1 SpringMVC的执行流程(面试考点)
@Controller//
public class HelloController {
@RequestMapping("/hello")//
public ModelAndView hello(){
ModelAndView mv = new ModelAndView();
//将相应数据保存在ModelAndView对象中 本质就是将数据保存在request域中
mv.addObject("username","admin");
mv.setViewName("success");
System.out.println("helloController.....");
//此时为试图的完整路径 第一个/表示项目的web目录
//如果返回的只有试图名称 则需要配置试图解析器
return mv;
}
}
- 在其中涉及到的HandlerMapping 处理器映射器 他将决定由哪一个处理器来处理当前请求
- HandlerAdaptor 处理器适配器 他决定由映射到的处理器中的哪一个方法来处理当前请求
- ViewResolver 试图解析器 他决定返回的试图如何映射
①用户发送请求至前端控制器DispatcherServlet。
②DispatcherServlet收到请求调用HandlerMapping处理器映射器。
③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
④DispatcherServlet调用HandlerAdapter处理器适配器。
⑥Controller执行完成返回ModelAndView。
⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
⑨ViewReslover解析后返回具体View。
⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)DispatcherServlet响应用户。
3.4. SpringMVC组件解析
1.前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
2.处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3.处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
4.处理器:Handler
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
5.视图解析器:View Resolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。
6.视图:View
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面
3.5. SpringMVC注解解析
@RequestMapping
作用:用于建立请求 URL 和处理请求方法之间的对应关系
位置:
类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径
属性:
value:用于指定请求的URL。它和path属性的作用是一样的
method:用于指定请求的方式
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
@Controller//
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(value = "/hellom",method = RequestMethod.GET)//method = RequestMethod.POST 表明该方法只接受post请求
public ModelAndView hello(){
ModelAndView mv = new ModelAndView();
//将相应数据保存在ModelAndView对象中 本质就是将数据保存在request域中
mv.addObject("username","admin");
mv.setViewName("success");
System.out.println("helloController.....");
//此时为试图的完整路径 第一个/表示项目的web目录
//如果返回的只有试图名称 则需要配置试图解析器
return mv;
}
}
@Controller//
@RequestMapping("/hello")
public class HelloController {
// @RequestMapping(value = "/hellom",method = RequestMethod.GET)//method = RequestMethod.POST 表明该方法只接受post请求
//params = {"username"} 表示请求中必须携带username参数
//params = {"username=admin"} 表示请求中必须携带username参数 而且他的值必须是admin
// params = {"username!=admin"}表示请求中必须携带username参数 而且他的值不能为admin
// params = {"username!=admin","age"}表示请求中必须携带username和age参数 但是username的值不能为admin
@GetMapping(value = "/hellom" ,params = {"username!=admin","age"})//作用和上边的配置是一样的 只能处理get请求
public ModelAndView hello(){
ModelAndView mv = new ModelAndView();
//将相应数据保存在ModelAndView对象中 本质就是将数据保存在request域中
mv.addObject("username","admin");
mv.setViewName("success");
System.out.println("helloController.....");
//此时为试图的完整路径 第一个/表示项目的web目录
//如果返回的只有试图名称 则需要配置试图解析器
return mv;
}
}
1.mvc命名空间引入
命名空间:
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
约束地址:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
2.组件扫描
SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用<context:component-scan base-package=“com.ssm.controller"/>进行组件扫描。
试图解析器
<!-- 试图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
prefix前缀
suffix 后缀
通过试图解析器 使用前缀 + 试图逻辑名(处理器中返回的试图的名称) + 后缀 生成响应试图的物理路径
3.6. 知识要点
SpringMVC的相关组件
- 前端控制器:DispatcherServlet
- 处理器映射器:HandlerMapping
- 处理器适配器:HandlerAdapter
- 处理器:Handler
- 视图解析器:View Resolver
- 视图:View
SpringMVC的注解和配置
- 请求映射注解:@RequestMapping
- 视图解析器配置:
- REDIRECT_URL_PREFIX = “redirect:”
- FORWARD_URL_PREFIX = “forward:”
- prefix = “”;
- suffix = “”;
4.SpringMVC的数据响应
1)页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
2) 回写数据
- 直接返回字符串
- 返回对象或集合
4.1.SpringMVC的数据响应-页面跳转-返回字符串形式(应用)
4.2.SpringMVC的数据响应-页面跳转-返回ModelAndView形式(应用)
在Controller中方法返回ModelAndView对象,并且设置视图名称
@RequestMapping("/hello2")
public ModelAndView hello2(){
ModelAndView mv = new ModelAndView();
mv.addObject("username","张三");
mv.setViewName("success");
return mv;
}
当放回字符串的时候 进行转发到页面
@RequestMapping("/hello3")
public String hello3( ){
return "forward:/WEB-INF/jsp/success.jsp";
}
//返回ModelAndView 转发到页面
@RequestMapping("/hello4")
public ModelAndView hello4( ){
ModelAndView mv = new ModelAndView();
mv.addObject("username","李四");
mv.setViewName("forward:/WEB-INF/jsp/success.jsp");
return mv ;
}
4.3. ModelAndView对象的创建 (model)
@RequestMapping("/hello5")
public ModelAndView hello5( ModelAndView mv){
mv.addObject("username","李四");
mv.setViewName("forward:/WEB-INF/jsp/success.jsp");
return mv ;
}
@RequestMapping("/hello6")
public String hello6(Model model){
model.addAttribute("username","王五");
return "success" ;
}
@RequestMapping("/hello7")
public View hello7(Model model){
model.addAttribute("username","王五");
View view = new InternalResourceView("/WEB-INF/jsp/success.jsp");
return view ;
}
@RequestMapping("/hello8")
public ModelAndView hello8( ){
ModelAndView mv = new ModelAndView("seccess");
mv.addObject("username","王五");
return mv;
}
4.4.SpringMVC的数据响应-回写数据-直接回写字符串(应用)
@RequestMapping("/hello9")
public void hello9( HttpServletRequest req , HttpServletResponse resp) throws IOException {
resp.getWriter().write("hello SpringMVC");
}
@ResponseBody //告知SpringMVC框架 不进行视图跳转 直接进行数据响应
@RequestMapping("/hello10")
@ResponseBody
public String hello10( ) throws IOException {
return "Spring MVC Hello";
}
4.5. -SpringMVC的数据响应-回写数据-直接回写json格式字符串(应用)
@RequestMapping(value="/hello11")
@ResponseBody
public String hello11() throws IOException {
return "{\"username\":\"zhangsan\",\"age\":18}";
}
son转换工具jackson进行转换,通过jackson转换json格式字符串,回写字符串,导入jackson坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.3</version>
</dependency>
@RequestMapping(value="/hello12")
@ResponseBody
public String hello12() throws IOException {
List<String> list = new ArrayList<>();
list.add("aaaa");
list.add("bbbb");
list.add("cccc");
//将list集合转换为json
ObjectMapper om = new ObjectMapper();
String jsonStr = om.writeValueAsString(list);
return jsonStr;
}
4.6.SpringMVC的数据响应-回写数据-返回对象或集合(应用)
通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:
就是让SpringMVC自动帮助我们将对象或集合转换为json串 然后回传给客户端
<!-- 自动完成数据的转换 将数据映射为json格式-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
@RequestMapping(value="/hello13")
@ResponseBody
public List<String> hello13() throws IOException {
List<String> list = new ArrayList<>();
list.add("aaaa");
list.add("bbbb");
list.add("cccc");
return list;
}
4.7.SpringMVC的数据响应-回写数据-返回对象或集合2(应用)
在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置
<mvc:annotation-driven/>
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用
<mvc:annotation-driven />替代注解处理器和适配器的配置。
同时使用<mvc:annotation-driven />
默认底层就会集成jackson进行对象或集合的json格式字符串的转换
4.8.SpringMVC的数据响应-知识要点小结(理解,记忆)
1) 页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
2) 回写数据
- 直接返回字符串
- HttpServletResponse 对象直接写回数据,HttpServletRequest对象带回数据,Model对象带回数据或者@ResponseBody将字符串数据写回
- 返回对象或集合
list.add(“bbbb”);
list.add(“cccc”);
return list;
}
## 4.7.SpringMVC的数据响应-回写数据-返回对象或集合2(应用)
在方法上添加@ResponseBody就可以返回json格式的字符串,但是这样配置比较麻烦,配置的代码比较多,因此,我们可以使用mvc的注解驱动代替上述配置
```xml
<mvc:annotation-driven/>
在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
使用<mvc:annotation-driven />自动加载 RequestMappingHandlerMapping(处理映射器)和
RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用
<mvc:annotation-driven />替代注解处理器和适配器的配置。
同时使用<mvc:annotation-driven />
默认底层就会集成jackson进行对象或集合的json格式字符串的转换
4.8.SpringMVC的数据响应-知识要点小结(理解,记忆)
1) 页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
2) 回写数据
- 直接返回字符串
- HttpServletResponse 对象直接写回数据,HttpServletRequest对象带回数据,Model对象带回数据或者@ResponseBody将字符串数据写回
- 返回对象或集合
@ResponseBody+<mvc:annotation-driven/>
5.SpringMVC请求处理
客户端请求参数的格式是:name=value&name=value……
服务器端要获得请求的参数,有时还需要进行数据的封装,SpringMVC可以接收如下类型的参数
- 基本类型参数
- POJO类型参数
- 集合类型参数
5.1. 请求参数为基本类型
<h1><a href="user/findUser?uid=10010">根据id查询特定用户</a> </h1>
@Controller
@RequestMapping("/user")
public class MVCRespController {
@RequestMapping("/findUser")
public String findUser(String uid){
System.out.println("查询用户成功!用户的id为="+uid);
return "success";
}
}
基本数据类型作为参数传递的时候 要求前端请求的参数名称和处理器中的方法的参数名必须保持一致 而且严格区分大小写
<h1><a href="user/findUser?uid=10010&flag=true">根据id查询特定用户</a> </h1>
@Controller
@RequestMapping("/user")
public class MVCRespController {
@RequestMapping("/findUser")
public String findUser(Integer uid,Boolean flag){
System.out.println("查询用户成功!用户的id为="+uid +"---flag="+flag);
return "success";
}
}
在WEB后端中 Servlet接受请求参数的时候 无论前端传递过来的参数是什么类型 Servlet从reques’t中得到参数都是String类型 SpringMVC是如何将参数完成类型的转换的呢?
原因就在于spring内置了大量的类型转换器 可以自动完成由String类型到常见类型的转换
5.2.请求参数为POJO类型
User
public class User {
private String username;
private Integer age;
private String password;
private Address address;
Address
public class Address {
private String provinceName;
private String cityName;
index.jsp
<form action="/user/saveUser" method="post">
用户名:<input type="text" name="username" ><br/><br/>
密码:<input type="text" name="password" ><br/><br/>
年龄:<input type="text" name="age" ><br/><br/>
省份名称:<input type="text" name="address.provinceName" ><br/><br/>
城市名称:<input type="text" name="address.cityName" ><br/><br/>
</form>
处理器
@RequestMapping("/saveUser")
public String saveUser(User user){
System.out.println("保存用户:" +user);
return "success";
}
springmvc会将前端传递过来 的数据封装称一个POJO
5.3. 请求参数为POJO类型包含集合类型
public class User {
private String username;
private Integer age;
private String password;
private Address address;
private List<String> hobby;
private Map<String, Integer> score;
index.jsp
<form action="/user/saveUser" method="post">
用户名:<input type="text" name="username" ><br/><br/>
密码:<input type="text" name="password" ><br/><br/>
年龄:<input type="text" name="age" ><br/><br/>
省份名称:<input type="text" name="address.provinceName" ><br/><br/>
城市名称:<input type="text" name="address.cityName" ><br/><br/>
兴趣爱好1:<input type="text" name="hobby[0]"><br/><br/>
兴趣爱好2:<input type="text" name="hobby[1]"><br/><br/>
兴趣爱好3:<input type="text" name="hobby[2]"><br/><br/>
成绩1:<input type="text" name="score['java']"><br/><br/>
成绩2:<input type="text" name="score['spring']"><br/><br/>
成绩3:<input type="text" name="score[mybatis]"><br/><br/>
<input type="submit" value="提交">
</form>
<form action="/user/saveUser" method="post">
用户名:<input type="text" name="username" ><br/><br/>
密码:<input type="text" name="password" ><br/><br/>
年龄:<input type="text" name="age" ><br/><br/>
省份名称:<input type="text" name="address.provinceName" ><br/><br/>
城市名称:<input type="text" name="address.cityName" ><br/><br/>
<%-- 使用checkbox 自动将同名的选中的选项封装到对应的属性中--%>
兴趣爱好<input type="checkbox" name="hobby" value="football">足球
<input type="checkbox" name="hobby" value="baskterball">篮球
<input type="checkbox" name="hobby" value="song">唱歌<br/><br/>
成绩1:<input type="text" name="score['java']"><br/><br/>
成绩2:<input type="text" name="score['spring']"><br/><br/>
成绩3:<input type="text" name="score[mybatis]"><br/><br/>
<input type="submit" value="提交">
</form>
5.4.中文乱码–请求参数乱码
SpringMVC 提供了对中文乱码的统一处理 web.xml
<!-- springmvc的统一的乱码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>
<!-- 对请求和响应启动过滤器-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 过滤请求的路径-->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
对于get请求 如果中文还是存在乱码 此时我们就需要在tomcat中进行配置
5.5.springmvc对于静态资源 的访问
如果静态资源无法正常访问:
1 资源的路径不正确
2 被拦截器拦截了
<!-- springmvc对于静态资源的处理 location 表示路径 mapping表示文件 ** 表示路径下的所有文件-->
<mvc:resources mapping="/imgs/**" location="/imgs/" />
<mvc:resources mapping="/js/**" location="/js"/>
<mvc:resources mapping="/css/**" location="/css"/>
cation 表示路径 mapping表示文件 ** 表示路径下的所有文件–>
<mvc:resources mapping="/imgs/" location="/imgs/" />
<mvc:resources mapping="/js/" location="/js"/>
<mvc:resources mapping="/css/**" location="/css"/>
5.6.SpringMVC对于AJAX请求的参数的处理
在以后的开发中,所有jsp页面 的进入 都是需要经过Controller
index.jsp
<%--
Created by IntelliJ IDEA.
User: Adminstrator
Date: 2021/4/28
Time: 9:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" >
$(function (){
$("#btn").on("click",function (){
//表单数据序列化 会对数据进行编码 编码之后如果想要得到元数据 则需要解码
var paramForm = $("#userForm").serialize();
//对数据进行解码
paramForm = decodeURIComponent(paramForm);
//JSON.stringify 将数据转换 为json字符串
alert(JSON.stringify(paramForm));
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/user/save",
data: JSON.stringify(paramForm),
contentType:"application/json;charset=utf-8"
});
})
})
</script>
</head>
<body>
<form id="userForm" action="">
姓名:<input type="text" name="username" value=""/><br/><br/>
年龄:<input type="text" name="age" value=""/><br/><br/>
<input type="button" id="btn" value="提交"/>
</form>
</body>
</html>
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
@ResponseBody
//RequestBody 该数据从请求体中获取
public void save(@RequestBody String userStr) throws JsonProcessingException {
//如果想要获取对象 则需要使用json工具再次将其转换为json对象
ObjectMapper mapper = new ObjectMapper();
System.out.println(userStr);
User user = mapper.readValue(userStr,User.class);
System.out.println(user);
}
}
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies>
ajax请求 提交表单数据封装为对象 同事处理器返回处理就结果
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" >
$(function (){
$("#btn").on("click",function (){
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/user/save",
data: $("#userForm").serialize(),
success:function (data){//成功之后的回调函数
alert(data);
}
});
})
})
</script>
</head>
<body>
<form id="userForm" action="">
姓名:<input type="text" name="username" value=""/><br/><br/>
年龄:<input type="text" name="age" value=""/><br/><br/>
<input type="button" id="btn" value="提交"/>
</form>
</body>
</html>
处理器
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(User user) throws JsonProcessingException {
System.out.println(user);
return "success";
}
}
如果处理器返回的是中文,则中文会出现乱码,如何解决乱码问题:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wb4Hqwfn-1620786454333)(assets/image-20210428141610088.png)]
使用表单的方式提交表单请求:
<form action="/user/update" method="post">
姓名:<input type="text" name="username" value=""/><br/><br/>
年龄:<input type="text" name="age" value=""/><br/><br/>
<input type="submit" value="提交"/>
</form>
@RequestMapping("/update")
public String update(String username,Integer age){
System.out.println("username = " + username);
System.out.println("age = " + age);
return "";
}
以上处理方式 要求表单元素的name属性值必须和请求的方法的参数名保持一致
如果出现不一致 ,该如何处理:
@RequestMapping("/update")
// RequestParam请求参数设置 value指的是提交过来的参数的名称 required是否必须 defaultValue当接受不到的时候的默认值
public String update(@RequestParam(value = "username",required = false,defaultValue ="springmvc") String name,Integer age){
System.out.println("username = " + name);
System.out.println("age = " + age);
return "";
}