概述
定义
- SpringMVC技术与Servlet技术功能等同,均属于web层开发技术
- SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
-
功能
-
主要用来替换之前的 servlet ;将之前写的 Servlet 换成后面所用的 Controller;
优点
使用简单、开发便捷(相比于Servlet)、灵活性强
实例入门
导包
- 需要导入两个jar包:
- spring-web
- spring-webmvc
- 还有spring核心包和spring-aop的包(涉及到包扫描)
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">
<servlet>
<servlet-name>2403mvc</servlet-name>
<!-- springmvc -webmvc -->
<servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 读取spring相关配置文件; -->
<param-name>ContextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</init-param>
<!-- 和servlet的配置一致;为正数的时候表示当服务启动的时候就会将所有的
Controller进行加载; -->
<load-on-startup>1</load-on-startup>
</servlet>
applicationContext-mvc.xml
java
执行过程
浏览器地址栏中输入http://localhost/2403mvc/toIndex;
解析获取真实地址toIndex与web.xml中的url-pattern进行匹配;与/进行比对;
找对应的servlet-name,去找到对应的servlet标签中的servlet-name一致;
找servlet-class,确定是DispatcherServlet(前端控制器);
前端控制器,初始化的时候加载了applicationContext-mvc.xml,其中使用包扫描将controller包
下面的所有类交给spring容器进行管理;
去该包下面的类中找注解@Controller;
去找@XXXMapping的方法,根据请求方法去找到对应的,拿取真实路径与该注解中的
urlpattern进行比对,如果一致,则执行该方法;
该方法中如果返回值是string类型,则跳转到返回值的页面中。
springmvc运行原理
<servlet-mapping>
<servlet-name>2403mvc</servlet-name>
<!-- 默认情况下就是/ 表示除了jsp以外的所有请求; -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
applicationContext-mvc.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"
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">
<context:component-scan base-package="cn.ry.controller"></context:componentscan>
</beans>
Java
@Controller
public class UserController {
@RequestMapping("/toIndex")
public String toIndex() {
return "index.jsp";
}
}
执行过程
- 浏览器地址栏中输入http://localhost/2403mvc/toIndex;
- 解析获取真实地址toIndex与web.xml中的url-pattern进行匹配;与/进行比对;
- 找对应的servlet-name,去找到对应的servlet标签中的servlet-name一致;
- 找servlet-class,确定是DispatcherServlet(前端控制器);
- 前端控制器,初始化的时候加载了applicationContext-mvc.xml,其中使用包扫描将controller包下面的所有类交给spring容器进行管理;
- 去该包下面的类中找注解@Controller;
- 去找@XXXMapping的方法,根据请求方法去找到对应的,拿取真实路径与该注解中的 urlpattern进行比对,如果一致,则执行该方法;
- 该方法中如果返回值是string类型,则跳转到返回值的页面中。
SpringMVC运行原理
- 客户端发送请求到前端控制器;
- 前端控制器去请求处理器映射器(多种),返回处理器执行器链和拦截器链,到前端控制器;
- 前端控制器去请求处理器适配器,处理器适配器按照相应的规则,去查找并执行handler,返回ModelAndView到处理适配器,再返回到前端控制器;
- 前端控制器将拿到的ModelAndView去请求视图解析器,视图解析器解析后返回model和view对象给前端控制器;
- 前端控制器将model注入到view中,生成静态页面,返回给前端控制器;
- 前端控制器将html文件返回到客户端,客户端重新渲染。
同步请求定义方式
- 在类上面添加@Controller注解;
- 同时开启包扫描 <context:component-scan base-package="cn.ry.controller">/context:compon ent-scan 替换了以前的@WebServlet;
@RequestMapping
- 类级别注解、方法级别的注解;
- 核心属性value、path用来配置url;
- 如果在类上面添加了该注解并且配置了url,则方法中的url都需要拼接类上面的url;
- method属性,可以定义请求方式,如: GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE,但是通常不使用,如果直接声明了请求方式,则直接使用衍生出来的注解即可:如@GetMapping @PostMapping、@PutMapping:新增|修改; @PATCH:批处理的时候;@DELETE:删除的时候;
返回结果类型
常用String类型
//返回string类型:相当于直接跳转到该视图也就是页面中,/开头为绝对路径;
@RequestMapping("/toIndex")
public String toIndex() {
return "/index.jsp";
}
转发
@RequestMapping("/zf")
public String zf() {
return "forward:/index.jsp";
}
重定向
@RequestMapping("/cdx")
public String cdx() {
return "redirect:/index.jsp";
}
无返回值类型
//借助之前的转发和重定向进行资源跳转,里面必须有request 和response对象;
@RequestMapping("/wufanhui")
public void wufanhui(HttpServletRequest req,HttpServletResponse resp) throws
ServletException, IOException {
//跳转资源:
req.getRequestDispatcher("/index.jsp").forward(req, resp);
}
返回ModeAndView
//返回modelandview对象,其中使用setViewName表示跳转视图;addA..进行传值;
@RequestMapping("/mv")
public ModelAndView mv() {
ModelAndView mv = new ModelAndView();
mv.setViewName("/index.jsp");
return mv;
}
请求参数
- HttpServletRequest request;
- String getParameter(String name) 根据请求参数名获取参数值;
- String[] getParameterValues(String name) 复选框这种类型根据一个参数名返回一个数组;
- Map getParameterMap(); 返回所有参数名和对应的参数值集合
- void setAttribute(String key,Object value); 一次请求中进行传值;
- request.getRequestDispatcher("资源").forward(request,response);搭配上面的一次请求传值一起使用;
- HttpServletResponse response;
- 响应信息:getWriter().write("数据");
- getOutputStream().print();
- addCookie(Cookie cookie):将cookie发送到客户端;
- void sendRedirect(“路径”) 重定向;
- HttpSession session;
- void setAttribute(String key,Object value); 一次会话中进行传值;
- Model model;
- ModelMap modelMap;
- 用来在controller中相当于request对象传值,不能用来代替session域对象传值
简单数据类型
同名
如果请求参数名字和方法中参数名字相同则直接映射;
不同名
不同名并不能直接映射,映射到的值是null;
解决不同名映射
使用到了参数级别的注解 @RequetParam// 使用方式 添加到参数前//name: 用来起别名和页面中的请求参数保持一致;//required :默认值是 true, 如果 name 中的值和页面中的请求参数名字不一致,那么就会报错 400 ;如果改为 false 就不会报错;//defaultValue : 用来为当前参数设置默认值,此时 url 中都可以不拼接该请求参数 ;
自定义数据类型
相当于在方法中直接写类形参
- 要求请求参数名字 和类中的属性名保持一致;
- 要求实体类中必须有set方法;
- 如果请求参数名字和类中的属性名不一致,则映射失败,该属性映射为null
集合数据类型
数组类型
什么情况出现?参数名一致,值有多个。
用来取代以前的
request.getParameterValues();
//参数类型是String类型的数组,形参名和页面中的请求参数名保持一致;
@RequestMapping("/toIndex")
public String toIndex(String[] hobby,Model model) throws IOException {
System.out.println(Arrays.toString(hobby));
//model和modelMap类似于域对象用来进行同步请求传值的操作;
return "/index.jsp";
}
集合类型
集合类型是将多个对象同时进行操作,需要将多个对象封装到集合中添加。在方法中的形参标准写法以Dto扩展类形式进行获取,页面中参数名字以扩展类中的属性名
[
索引
]
方式进行编写。
HTML
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="user/jihe">
<!-- 部门 -->
部门名字:<input type="text" name="deptName">
<hr>
<!-- 用户1 -->
用户1基本信息:
用户名:<input type="text" name="list[0].name" id ="name">
密码:<input type="password" name="list[0].pwd" id ="pwd">
<hr>
用户2基本信息:
用户名:<input type="text" name="list[1].name" id ="name">
密码:<input type="password" name="list[1].pwd" id ="pwd">
<hr>
用户3基本信息:
用户名:<input type="text" name="name" id ="name">
密码:<input type="password" name="pwd1" id ="pwd">
<hr>
<!-- 提交按钮 -->
<input type="submit" value="保存">
</form>
</body>
</html>
Java
package cn.ry.pojo;
import java.util.List;
public class Dept {
private Integer id;
private String deptName;
//直接将用户类作为属性即可:
private List<User> list;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
@Override
public String toString() {
return "Dept [id=" + id + ", deptName=" + deptName + ", list=" + list +
"]";
}
}
@GetMapping("/jihe")
public String jihe(Dept dept) {
System.out.println(dept);
return "/index.jsp";
}
类型转换
日期类型转换
实体类中的涉及到日期属性的时候,可以选择
String
类型的,也可以选择
Date
类型(
java.util
)
之前的类型转换
//SimpleDateFormat:
public class DateUtil {
//类型转换:
public Date convert(String rq) {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
Date parse;
try {
parse = sf.parse(rq);
return parse;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
第一种:根据自定义类型转换进行实现
- 创建日期工具类,需要去实现转换器接口
public class DateUtil implements Converter<String, Date>{
//类型转换:
public Date convert(String rq) {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
Date parse;
try {
parse = sf.parse(rq);
return parse;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
- xml中进行配置,配置包含转换器、将当前工具类交给spring容器管理以及最新的处理器映射器和适配器;
- 使用之前需要引入mvc的命名空间和约束
<?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
https://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<context:component-scan base-package="cn.ry.controller">
</context:component-scan>
<!-- 需要将创建的工具类交给spring容器管理 -->
<bean id="dateUtil" class="cn.ry.utils.DateUtil"></bean>
<!-- 配置的转换器 -->
<bean id="cs"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="dateUtil"/>
</set>
</property>
</bean>
<!-- mvc注解驱动: -->
<mvc:annotation-driven conversion-service="cs"></mvc:annotation-driven>
</beans>
- 配置完以后在controller的方法中,请求参数直接Date类型即可映射
第二种方式
- 直接在实体类的日期类型的属性上添加注解
@DateTimeFormat ( pattern = "yyyy-MM-dd" )private Date rq ;
- xml
<!-- mvc 注解驱动:使用最新的处理器映射器和处理器适配器 --><mvc:annotation-driven></mvc:annotation-driven>
今天的分享到此结束,博主创作不易,点个关注不迷路。感谢!!!