Spring-mvc入门(一)
简介
- Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中。
- Spring MVC主要由DispatcherServlet、处理器映射【找控制器】、适配器【调用控制器的方法】、控制器【业务】、视图解析器、视图组成。
第一步,导入jar包
第二步,在web.xml配置DispatcherServlet
<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:DispatcherServlet-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
第三步,在src目录下创建DispatcherServlet-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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
</beans>
第四步:配置DispatcherServlet-servlet.xml
<!-- 1. 配置处理器映射,springmvc默认的处理器映射器
BeanNameUrlHandlerMapping:根据bean的name属性的url去找handlerController -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 2. 配置处理器适配置器执行Controller -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 3.配置一个控制器 -->
<bean name="/user.html" class="com.gyf.backoffice.web.controller.UserController"/>
<!-- 4.配置springmvc视图解析器
视图解析器解析的视频路径为:前缀 + 后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views"/>
<property name="suffix" value=".jsp"/>
</bean>
第五步:创建个Controller控制器
第六步:创建一个userList.jsp页面
第七步:运行项目,访问路径
执行流程
Url处理器映射(了解)
-
BeanNameUrlHandlerMapping
功能:寻找Controller
根据url请求去匹配bean的name属性,从而获取Controller
-
SimpleUrlHandlerMapping
功能:寻找Controller
根据浏览器url匹配简单url的key,key就是Controller的id找到Controller
访问路径:
http://localhost:8080/user1.html
http://localhost:8080/user2.html
http://localhost:8080/user3.html -
ControllerClassNameHandlerMapping
功能:寻找Controller
根据类名(MyController)类名.html来访问,类名首字母小写
处理器适配器
- SimpleControllerHandlerAdapter
功能:执行controller
调用controller里面方法,返回modelAndView
- HttpRequestHandlerAdapter
执行控制器
负责调用实现HttpRequestHandler接口的控制器
注意:两个处理器适配器可以共存
命令控制器
Springmvc通过命令设计模式接受页面参数
添加页面
<form action="${pageContext.request.contextPath}/command.do" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
性别:<input type="text" name="gender"><br>
生日:<input type="text" name="birthday"><br>
<input type="submit">
</form>
Command控制器
Info.jsp
DispatchServelt-sevlet配置文件
测试
结果:默认日期格式只能2017/10/11格式,其它格式接收参数会为空
乱码问题
- POST请求乱码
在web.xml中配置
<!-- 配置编码过滤器 -->
<filter>
<filter-name>EncodingFilter</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>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- GET请求乱码
Tomcat8 默认进行了url编码,get请求不乱码,Tomcat7会乱码
日期类型转换
- springmvc默认接收的日期格式为yyyy/MM/dd,如果添加其它格式,只要在CommandCommandController中重写一个方法
SpringMVC注解开发
修改配置文件DispatchServlet-Servlet.xml
<!-- 1.配置注解扫描位置 -->
<context:component-scan base-package="com.hlk.web.controller"/>
<!-- 2. 配置处理器映射,通过注解来查找 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 3.配置注解处理适配器来执行控制器的方法 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- 配置springmvc视图解析器
视图解析器解析的视频路径为:前缀 + 后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views"/>
<property name="suffix" value=".jsp"/>
</bean>
UserController
@Controller
public class UserController {
@RequestMapping("/list")
public String list() {
return "userList";
}
}
接收请求参数
参数类型有:基本类型,int,String等等基本类型, Pojo类
Struts2参数:基于属性封装,在action会添加属性,提供set方法。
Springmvc参数封装:基于方法进行封装。
- 提供form表单
<form action="${pageContext.request.contextPath}/register.do" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
性别:<input type="text" name="gender"><br>
生日:<input type="text" name="birthday"><br>
爱好:<input type="checkbox" name="hobby" value="1">打球
<input type="checkbox" name="hobby" value="2">玩
<input type="checkbox" name="hobby" value="3">睡
<input type="submit">
</form>
- Controller中添加接收参数的方法
@RequestMapping("register")
public String register(String username, String password, String gender, String birthday, String[] hobby) {
System.out.println(username);
System.out.println(password);
System.out.println(gender);
System.out.println(birthday);
for (String s : hobby) {
System.out.println(s);
}
return "success";
}
接收POJO类型
一个POJO类
public class User {
private String username;
private String password;
private String gender;
private Date birthday;
private String[] hobby;
}
Controller
@RequestMapping("register2")
public String register2(User user) {
System.out.println(user);
return "success";
}
接收包装类型参数
把User封装成一个属性
public class UserExt {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
提交的表单
<!--注意,这里的那么必须要添加user.-->
<form action="${pageContext.request.contextPath}/register3.do" method="post">
用户名:<input type="text" name="user.username"><br>
密码:<input type="text" name="user.password"><br>
性别:<input type="text" name="user.gender"><br>
生日:<input type="text" name="user.birthday"><br>
爱好:<input type="checkbox" name="user.hobby" value="1">打球
<input type="checkbox" name="user.hobby" value="2">玩
<input type="checkbox" name="user.hobby" value="3">睡
<input type="submit">
</form>
Controller
@RequestMapping("register3")
public String register3(UserExt user) {
System.out.println(user.getUser().toString());
return "success";
}
接收集合List类型参数
UserList的封装
public class UserExt {
private List<User> userList;
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
Form表单
<!-- 注意name的属性值-->
<form action="${pageContext.request.contextPath}/register4.do" method="post">
用户名:<input type="text" name="userList[0].username"><br>
密码:<input type="text" name="userList[0].password"><br>
=============================================<br>
用户名:<input type="text" name="userList[1].username"><br>
密码:<input type="text" name="userList[1].password"><br>
<input type="submit">
</form>
Controller
@RequestMapping("register4")
public String register4(UserExt user) {
System.out.println(user.getUserList());
return "success";
}
接收集合Map类型参数
UserExt
public class UserExt {
private Map<String, Object> info;
public Map<String, Object> getInfo() {
return info;
}
public void setInfo(Map<String, Object> info) {
this.info = info;
}
}
Form表单
<!--注意name-->
<form action="${pageContext.request.contextPath}/register5.do" method="post">
用户名:<input type="text" name="info['username']"><br>
密码:<input type="text" name="info['password']"><br>
<input type="submit">
</form>
Controller
@RequestMapping("register5")
public String register5(UserExt user) {
System.out.println(user.getInfo().get("username"));
System.out.println(user.getInfo().get("password"));
return "success";
}
SpringMVC与Strut2的区别
- 实现机制
Struts2是基于过滤器实现的。
Springmvc基于servlet实现。 - 运行速度
Servlet比过滤器快。
Struts2是多例
每一次请求,都会创建一个Action对象
请求来了以后,struts2创建多少个对象:ActionContext,valuestack,UAction,ActionSuport,ModelDriven
Springmvc是单例。
同一个Controller请求,只会创建一个Controller
- 参数封装来分析
Struts基于属性进行封装,Action有参数属性。
Springmvc基于方法封装,参数是写在Controller的方法。
页面的回显
配置一个列表方法Controller
@RequestMapping("list1")
public String list1(Model model) {
List<User> list = new ArrayList<>();
User user1 = new User();
user1.setId(1);
user1.setUsername("张1");
user1.setPassword("123");
list.add(user1);
User user2 = new User();
user2.setId(2);
user2.setUsername("张2");
user2.setPassword("123");
list.add(user2);
User user3 = new User();
user3.setId(3);
user3.setUsername("张3");
user3.setPassword("123");
list.add(user3);
model.addAttribute("userList", list);
return "userList";
}
页面
<table border="1">
<c:forEach items="${userList}" var="list">
<tr>
<td>${list.username}</td>
<td>${list.password}</td>
<td><a href="${pageContext.request.contextPath}/edit.do?id=${list.id}">修改</a></td>
</tr>
</c:forEach>
</table>
编辑Controller
// 模拟接收id,根据id获取数据,然后回显
@RequestMapping("edit")
public String edit(int id, Model model) {
System.out.println(id);
User user = new User();
user.setUsername("张1");
user.setPassword("123");
model.addAttribute("user", user);
return "index";
}
回显编辑页面的数据
<form action="${pageContext.request.contextPath}/register5.do" method="post">
用户名:<input type="text" name="" value="${user.username}"><br>
密码:<input type="text" name="" value="${user.password}"><br>
<input type="submit">
</form>
URL模版映射
修改url格式
@Pathariable:{}里面参数注入后面参数里面
转发和重定
转发到不同一个控制器的方法
重定向,只需要把forward改成redirect