SpringMVC学习笔记_01
SpringMVC学习笔记_01
1、JAVAEE体系结构
- JAVAEE体系结构图如下所示:
2、什么是springmvc?
- 什么是mvc?
- Model1
- Model2
- Model1
- SpringMVC是什么?
- SpringMVC是一个web层mvc框架,类似struts2。
- SpringMVC和Spring?
- Springmvc是Spring的组成部分。
- SpringMVC执行流程(运行原理)
- 回忆Struts2执行流程:
- 前端控制器:StrutsPrepareAndExcuteFilter拦截请求(控制层):拦截请求,转发请求
- 寻找Action执行,处理请求数据
- ActionMapping去寻找执行类Action --> UserAction
- 找到ActionProxy:StrutsActionProxy extends DefaultActionProxy
- 通过代理类ActionProxy根据struts.xml寻找到真正的执行类Action
- SpringMVC执行流程(运行原理),如下图所示:
- 回忆Struts2执行流程:
3、springmvc第一个程序案例
3.1、不使用jsp视图解析器+使用jsp视图解析器
(1)使用eclipse,创建一个动态的web工程
其中Dynamic web module version版本选择 2.5
,这样兼容性好一些;
Default output folder设置为 WebRoot\WEB-INF\classes
;
Content directory设置为 WebRoot
;
更改JRE System Library[J2SE-1.5]为 JRE System Library[jre1.7.0_80]
;
删掉没用的库:EAR Libraries
;
增加服务器运行环境库 Server Runtime
,不然jsp文件会报错。
创建完项目后,将整个项目的编码改为UTF-8。
操作步骤:选中项目右键 --> Properties --> Resource --> Text file encoding --> Other中选择UTF-8。
对于动态的java web项目,为了工程目录结构的清爽,我们将引入的jar包放到“Web App Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。
对于普通的java项目,为了工程目录结构的清爽,我们将引入的jar包放到“Referenced Libraries”中,可以通过“小三角”选择是否“Show 'Referenced Libraries' Node ”进行调节。
(2)导入springmvc的jar包
本案例共16个jar,如下图所示:
(3)在web.xml配置前端控制器:DispatcherServlet(入口)
<!-- 配置前端控制器:DispatcherServlet --><servlet ><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
我们还需要配置springmvc.xml文件的初始化参数,如下图所示:
(4)配置springmvc.xml
参考文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html
<?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 "><!-- 配置处理器映射器,springmvc默认的处理器映射器 --><!-- BeanNameUrlHandlerMapping:根据bean(自定义的Controller)的name属性的url去寻找执行类Handler(Action)即Controller --><bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean><!-- 配置处理器适配器,负责执行Controller,也是springmvc默认的处理器适配器 --><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean><!-- 配置自定义的Controller:UserController --><bean name="/hello.do" class="com.itheima.controller.UserController"></bean><!-- 配置jsp视图解析器,InternalResourceViewResolver负责解析出真正的逻辑视图 --><!-- 后台返回逻辑视图:index,jsp视图解析器解析出真正的物理视图:前缀+逻辑视图+后缀 ==>/WEB-INF/jsps/index.jsp --><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsps/"></property><property name="suffix" value=".jsp"></property></bean>
</beans>
(5)自定义Controller(相当于Struts2里面的Action)
public class UserController implements Controller {public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {// 接收请求,接收参数,验证参数,处理请求// 封装参数,调用业务方法,返回处理结果数据ModelAndView// 演示案例中我们只模拟下而已:向前台返回数据ModelAndView mv = new ModelAndView();mv.addObject("hello", "like xiaoyi");// 指定跳转的视图// 返回真实的物理视图,省略了8、9步// mv.setViewName("/WEB-INF/jsps/index.jsp");// 返回逻辑视图mv.setViewName("index");return mv;}
}
(6)定义视图页面
根据视图解析路径:WEB-INF/jsps/index.jsp
<body><h1>${hello}</h1>
</body>
(7)浏览器访问
访问地址:http://localhost:8080/day63_SpringMVC_01/hello.do
4、根据程序分析springmvc执行流程(画图)
- 该图同SpringMVC执行流程图(运行原理)
5、处理器映射器
5.1、配置默认处理器映射器(BeanNameUrlHandlerMapping)
功能:寻找Controller
根据url请求去匹配bean的name属性url,从而获取Controller
5.2、配置集中处理器映射器(SimpleHandlerMapping)
功能:寻找Controller
根据浏览器url匹配简单url的key,key通过Controller的id找到Controller
5.3、配置类名处理器映射器(ClassNameHandlerMapping)
功能:寻找Controller
直接根据类名(UserController),类名.do来访问,类名首字母小写
3个处理器映射器可以共存。均可以访问成功。
6、处理器适配器
6.1、配置默认处理器适配器(SimpleControllerHandlerAdapt)
功能:执行Controller
负责执行实现了Controller接口的后端控制器,例如:UserController,调用Controller里面的方法,返回ModelAndView。
默认处理器适配器源码分析,如下图所示:
6.2、配置请求处理器适配器(HttpRequestHandlerAdapter)
功能:执行Controller
负责执行实现了HttpRequestHandler接口的后端控制器。
演示过程:
自定义实现了接口HttpRequestHandler的实现类HttpController,如下图所示:
在springmvc.xml中配置自定义的bean,即自定义的HttpController,如下图所示:
上面的这种方式无限接近servlet的开发。
2个处理器适配器可以共存。
7、命令控制器
7.1、Controller简介
1、收集、验证请求参数并绑定到命令对象;
2、将命令对象交给业务对象,由业务对象处理并返回模型数据;
3、返回ModelAndView(Model部分是业务对象返回的模型数据,视图部分是逻辑视图名)。
- 普通控制器(继承接口Controller,继承接口HttpRequestHandler)
- 命令控制器(继承抽象类AbstractCommandController)
- 例子:跳转到添加页面,进行页面跳转,参数提交get请求或者post请求
- 参数控制器(类ParameterizableViewController)
Springmvc通过命令设计模式
接受页面参数。
7.2、演示:自定义命令控制器
示例如下:
(1)自定义命令控制器
package com.itheima.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;import com.itheima.domain.User;// 从页面接收参数,封装到JavaBean中,本例中的JavaBean是User
@SuppressWarnings("deprecation")
public class CommandController extends AbstractCommandController {// 指定把页面传过来的参数封装到对象,使用命令设计模式public CommandController() {this.setCommandClass(User.class);}@Overrideprotected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command,BindException errors) throws Exception {// 参数被封装进命令对象,这个过程很复杂,我们暂时不用管它,只要知道它使用的是命令设计模式即可// 把命令对象强转成User对象User user = (User) command;// 设置Model的数据,值可以是任意pojoModelAndView mv = new ModelAndView();mv.addObject("user", user);// 指定返回页面mv.setViewName("index");return mv;}
}
(2)定义javaBean
package com.itheima.domain;import java.util.Date;public class User {private Integer id;private String username;private String age;private Date birthday;private String address;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
(3)封装参数页面
文件位置:/day63_SpringMVC_01/WebRoot/WEB-INF/jsps/add.jsp
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body><form action="${pageContext.request.contextPath}/command.do" method="post">姓名:<input type="text" name="username" id="username"><br>年龄:<input type="text" name="age" id="age"><br>生日:<input type="text" name="birthday" id="birthday"><br>地址:<input type="text" name="address" id="address"><br><input type="submit" value="提交"></form>
</body>
</html>
(4)获取参数页面
文件位置:/day63_SpringMVC_01/WebRoot/WEB-INF/jsps/index.jsp
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body><h1>${user.username}---${user.age}---${user.birthday}---${user.address}</h1>
</body>
</html>
(5)跳转到add页面
由于add页面在WEB-INF下面不能直接访问,需要通过Controller来访问。
package com.itheima.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;public class ToAddController implements Controller {public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {// 跳转到add页面ModelAndView mv = new ModelAndView();mv.setViewName("add");return mv;}
}
(6)在springmvc.xml中配置bean
<!-- 配置自定义的CommandController:CommandController --><bean name="/command.do" class="com.itheima.controller.CommandController"></bean><!-- 配置自定义的ToAddController:ToAddController --><bean name="/toAdd.do" class="com.itheima.controller.ToAddController"></bean>
7.3、中文乱码解决
(1)解决get请求乱码
配置tomcat的编码,如下图所示:
(2)解决post请求乱码
在web.xml中,配置spring编码过滤器,如下所示:
<!-- 配置spring编码过滤器 --><filter><filter-name>characterEcoding</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>characterEcoding</filter-name><url-pattern>/*</url-pattern></filter-mapping>
7.4、时间类型转换
在CommandController类中重写initBinder()方法,示例代码如下:
// 从页面接收参数,封装到JavaBean中,本例中的JavaBean是User
@SuppressWarnings("deprecation")
public class CommandController extends AbstractCommandController {// 指定把页面传过来的参数封装到对象,使用命令设计模式public CommandController() {this.setCommandClass(User.class);}@Overrideprotected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {// 参数被封装进命令对象,这个过程很复杂,我们暂时不用管它,只要知道它使用的是命令设计模式即可// 把命令对象强转成User对象User user = (User) command;// 设置Model的数据,值可以是任意pojoModelAndView mv = new ModelAndView();mv.addObject("user", user);// 指定返回页面mv.setViewName("index");return mv;}@Overrideprotected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {String str = request.getParameter("birthday");if (str.contains("/")) {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy/MM/dd"), true));} else {binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));}}
}
7.5、参数控制器ParameterizableViewController
在springmvc.xml中配置参数控制器
- 注意:使用参数控制器:不用自己定义Controller了,可以直接使用toIndex.do进行访问。
8、注解开发
8.1、注解开发第一个入门程序
- 步骤如下:
- 创建一个动态的web工程,导入jar文件
- 配置web.xml
- 配置springmvc.xml文件:配置处理器映射器、配置处理器适配器、配置jsp视图解析器
- 自定义Controller类,使用注解开发:添加,返回到成功页面进行回显,点击修改回到添加页面,初步理解参数传递。
(1)创建一个动态的web工程,导入jar文件
详细过程同3、springmvc第一个程序案例
(2)配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"id="WebApp_ID" version="2.5"><display-name>day63_SpringMVC_01</display-name><!-- 配置spring编码过滤器 --><filter><filter-name>characterEcoding</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>characterEcoding</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置前端控制器:DispatcherServlet --><servlet ><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 隐式默认加载springmvc.xml文件,该文件需要满足2个规范:命名规范:servlet-name-servlet.xml => springmvc-servlet.xml路径规范:该文件必须放在WEB-INF目录下面--><!-- 显示配置加载springmvc.xml文件,即配置springmvc.xml文件的初始化参数 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list>
</web-app>
(3)配置springmvc.xml文件
配置扫描,把Controller交给spring管理、配置处理器映射器、配置处理器适配器、配置jsp视图解析器
<?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 "><!-- 配置扫描,把Controller交给spring管理 --><context:component-scan base-package="com.itheima"></context:component-scan><!-- 配置注解的处理器映射器,作用:寻找执行类Controller --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean><!-- 配置注解的处理器适配器,作用:调用Controller方法,执行Controller --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean><!-- 配置jsp视图解析器,InternalResourceViewResolver负责解析出真正的逻辑视图 --><!-- 后台返回逻辑视图:index,jsp视图解析器解析出真正的物理视图:前缀+逻辑视图+后缀 ==>/WEB-INF/jsps/index.jsp --><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsps/"></property><property name="suffix" value=".jsp"></property></bean>
</beans>
(4)自定义Controller类
@Controller // 相当于<bean id="userController" class="com.itheima.controller.UserController">,即相当于创建了一个UserController对象
@RequestMapping("/user")
public class UserController {// 请求映射注解@RequestMapping("hello") // 相当于访问/hello.dopublic String myHello() {// 表示springmvc返回了一个逻辑视图hello.jspreturn "hello";}
}
(5)定义hello页面
根据视图解析,需要在WEB-INF下面定义jsps文件夹,在里面定义一个hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body><h1>欢迎访问SpringMVC</h1>
</body>
</html>
(6)访问地址:http://localhost:8080/day63_SpringMVC_02/user/hello.do
8.2、注解开发流程图
注解开发流程图如下:
8.3、RequestMapping
功能:请求映射
几种写法:@RequestMapping("hello") -- 这种方式可以匹配任何的扩展名@RequestMapping("/hello.do")@RequestMapping(value="/hello.do")@RequestMapping(value="/hello.do",method=RequestMethod.GET)@RequestMapping(value="/hello.do",method=RequestMethod.POST)@RequestMapping(value="/hello.do", method={RequestMethod.GET,RequestMethod.POST})
浏览器直接访问、a标签都是get请求。
表单提交(指定post)、ajax指定post提交。
如果是get请求,写成了post浏览器会报405错误,如下图所示:
8.4、RequestMapping的根路径
@RequestMapping("/user")
public class UserController {@RequestMapping("save")public String save() {}@RequestMapping("update")public String update() {}@RequestMapping("find")public String find() {}
}
访问地址:http://localhost:8080/项目名/user/save.do@RequestMapping("/items")
public class ItemsController {@RequestMapping("save")public String save() {}@RequestMapping("update")public String update() {}@RequestMapping("find")public String find() {}
访问地址:http://localhost:8080/项目名/items/save.do
演示:自定义根路径
@Controller // 相当于<bean id="userController" class="com.itheima.controller.UserController">,即相当于创建了一个UserController对象
@RequestMapping("/user")
public class UserController {// 请求映射注解@RequestMapping("hello") // 相当于访问/hello.do// @RequestMapping(value="/hello.do",method=RequestMethod.POST)public String myHello() {// 表示springmvc返回了一个逻辑视图hello.jspreturn "hello";}
}
访问地址:http://localhost:8080/day63_SpringMVC_02/user/hello.do
8.5、RequestParam
value:参数名字,即入参的请求参数名字,如value="studentid"
表示请求的参数区中的名字为studentid的参数的值将传入。
required:是否必须,默认是true,表示请求中一定要有相应的参数
,否则将报400错误码。
defaultValue:默认值,表示如果请求中没有同名参数时的默认值
。
示例如下:
public String userList(@RequestParam(defaultValue="2",value="group",required=true) String groupid) {
}1、形参名称为groupid,但是这里使用value="group"限定参数名为group,所以页面传递参数的名必须为group。2、这里通过required=true限定groupid参数为必需传递,如果不传递则报400错误,由于使用了defaultvalue="2"默认值,即使不传group参数它的值仍为"2"。3、所以页面不传递group也不会报错,如果去掉defaultvalue="2"且定义required=true,则如果页面不传递group就会报错。
示例如下图所示:
@RequestParam的作用:给传递的参数起别名。
9、封装参数
- springmvc没有成员变量,那页面提交过来的参数该如何接收和进行传递呢?
- 答:把需要传递的参数对象放入方法里面,当你请求这个方法,向这个方法传递参数的时候,这个方法里面的对象会自动被创建,需要的参数会自动被封装到方法的对象里面。
分析接受参数类型:
基本类型int、String等基本类型。
Pojo类型
包装类型
集合类型Springmvc默认支持类型:HttpSession、HttpRequstServlet、Model等等。Struts2参数封装:基于属性驱动封装。
Springmvc参数封装:基于方法进行封装。
9.1、封装int类型参数
页面传递的参数都是字符串。
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveInt.do" method="post">ID:<input type="text" name="id" id="id"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收int类型参数 @RequestMapping("recieveInt")public String recieveInt(Integer id) {System.out.println(id);return "success";}
- 特别注意:
标签input的name的属性值id要与方法的形式参数名称id相同。
9.2、封装String类型参数
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveString.do" method="post">姓名:<input type="text" name="username" id="username"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收String类型参数 @RequestMapping("recieveString")public String recieveString(String username) {System.out.println(username);return "success";}
9.3、封装数组类型参数
- 分析:
封装数组是批量删除时使用,使用checkbox复选框,其value属性必须有值。
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveArray.do" method="post">ID:<input type="checkbox" name="ids" value="1" id="ids"><br>ID:<input type="checkbox" name="ids" value="2" id="ids"><br>ID:<input type="checkbox" name="ids" value="3" id="ids"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收数组类型参数 @RequestMapping("recieveArray")public String recieveArray(Integer[] ids) {System.out.println(ids);return "success";}
9.4、封装pojo类型参数
创建一个pojo类:
public class User {private Integer id;private String username;private String age;private Date birthday;private String address;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User [id=" + id + ", username=" + username + ", age=" + age + ", birthday=" + birthday + ", address="+ address + "]";}
}
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveUser.do" method="post">姓名:<input type="text" name="username" id="username"><br>年龄:<input type="text" name="age" id="age"><br>生日:<input type="text" name="birthday" id="birthday"><br>地址:<input type="text" name="address" id="address"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收pojo类型参数 @RequestMapping("recieveUser")public String recieveString(User user) {System.out.println(user);return "success";}
9.4、封装包装类型参数
创建一个包装类:
public class UserCustom {private User user;public User getUser() {return user;}public void setUser(User user) {this.user = user;}
}
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveUserCustom.do" method="post">姓名:<input type="text" name="user.username" id="username"><br>年龄:<input type="text" name="user.age" id="age"><br>生日:<input type="text" name="user.birthday" id="birthday"><br>地址:<input type="text" name="user.address" id="address"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收包装类型参数 @RequestMapping("recieveUserCustom")public String recieveUserCustom(UserCustom userCustom) {System.out.println(userCustom);return "success";}
9.5、封装集合类型参数
9.5.1、封装List集合类型参数
- 注意:
不能直接传递集合类型,需要把集合类型封装到包装类中。
我们先把List集合封装到包装类中。即:在包装类中定义List集合。提供getter和setter方法。
private List<User> userList;public List<User> getUserList() {return userList;}public void setUserList(List<User> userList) {this.userList = userList;}
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveList.do" method="post">姓名:<input type="text" name="userList[0].username" id="username"><br>年龄:<input type="text" name="userList[0].age" id="age"><br>姓名:<input type="text" name="userList[1].username" id="username"><br>年龄:<input type="text" name="userList[1].age" id="age"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收List结合类型参数 @RequestMapping("recieveList")public String recieveList(UserCustom userCustom) {System.out.println(userCustom);return "success";}
9.5.2、封装Map集合类型参数
我们先把Map集合封装到包装类中。即:在包装类中定义Map集合。提供getter和setter方法。
private Map<String, Object> maps = new HashMap<String, Object>();public Map<String, Object> getMaps() {return maps;}public void setMaps(Map<String, Object> maps) {this.maps = maps;}
页面的代码:
<hr size="12" color="blue"><form action="${pageContext.request.contextPath}/user/recieveMap.do" method="post">姓名:<input type="text" name="mps['username']" id="username"><br>年龄:<input type="text" name="mps['age']" id="age"><br><input type="submit" value="提交"></form>
接受参数的方法:
// 接收Map结合类型参数 @RequestMapping("recieveMap")public String recieveMap(UserCustom userCustom) {System.out.println(userCustom);return "success";}
9.6、思考:有了struts2,为什么还需要sprigmvc呢?
- 实现机制:
- struts2 底层是基于`过滤器`实现的。过滤器的底层是servlet。
- springmvc 底层基于`servlet`实现。servlet比过滤器快。
- 运行速度:
- struts2 是`多例`。
- 一个请求来了以后,struts2创建多少个对象?如下:
- ActionContext、ValueStack、UserAction、ActionSuport、ModelDriven等等。
- UserAction里面属性:User对象,userList集合对象等。属于成员变量,存活时间长。
- springmvc 是`单例`,因为是基于servlet的,servlet是单例的。
- 一个请求来了以后,springmvc 创建多少个对象?如下:
- Controller等等。
- 方法的参数属于局部变量,存活时间短。
- struts2 是`多例`。
- 参数封装来分析:
- struts 基于`属性驱动`进行封装。
- springmvc 基于`方法`进行封装,粒度更细。
10、页面回显
- springmvc使用
Model对象
进行页面数据回显,Model对象相当于javaweb时所学的application对象(应用域对象)
,所以Model对象中的数据可以通过EL表达式
进行获取。 - 有了Model对象,才可以向对象中放值,那么Model对象该如何创建呢?
- 答:`springmvc中放到方法里面的对象会自动被创建`,那么我们就把Model对象放到方法里面。
10.1、查询所有
页面的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%--引入jstl标签 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body><table border="1" style="color: blue"><tr><td>姓名</td><td>年龄</td><td>生日</td><td>地址</td><td>操作</td><tr/><c:forEach items="${userList}" var="user"><tr><td>${user.username}</td><td>${user.age}</td><td>${user.birthday}</td><td>${user.address}</td><td><a href="${pageContext.request.contextPath}/user/updateById.do?id${user.id}">修改</a></td><tr/> </c:forEach></table>
</body>
</html>
接受参数的方法:
// 查询所有@RequestMapping("listAll")public String listAll(Model model) {// 由于演示我们没有查询数据库,所以下面我们模拟几条数据List<User> userList = new ArrayList<User>();User user1 = new User();user1.setId(1);user1.setUsername("晓艺");user1.setAge("26");user1.setAddress("物资学院");user1.setBirthday(new Date());User user2 = new User();user2.setId(2);user2.setUsername("黑泽");user2.setAge("26");user2.setAddress("青年路");user2.setBirthday(new Date());User user3 = new User();user3.setId(3);user3.setUsername("奇遇");user3.setAge("28");user3.setAddress("物资学院");user3.setBirthday(new Date());userList.add(user1);userList.add(user2);userList.add(user3);// Model相当于application域对象model.addAttribute("userList", userList);return "list"; }
浏览器显示效果:
11、URL模版映射
- URL模版映射主要是为了实现请求
Restfull软件架构设计模式
。 - Restfull软件架构设计模式使得请求更简洁、更安全,方便于搜索引擎收录。
11.1、普通模式修改
页面的代码:
<td><a href="${pageContext.request.contextPath}/user/updateByIdNormal.do?id=${user.id}">修改</a></td>
接受参数的方法:
// 普通模式修改@RequestMapping("updateByIdNormal")public String updateByIdNormal(Integer id) {System.out.println(id);return "redirect:listAll.do";}
访问的地址为:http://localhost:8080/day63_SpringMVC_02/user/updateByIdNormal.do?id=1
11.2、Restfull风格设计模式修改
(1)初始Restfull风格设计模式修改
页面的代码:
<td><a href="${pageContext.request.contextPath}/user/updateByIdRestfull/${user.id}.do">修改</a> <!-- 把参数放在了请求的里面了 --></td>
接受参数的方法:
// 初始Restfull模式修改@RequestMapping("updateByIdRestfull/{id}")public String updateByIdRestfull(@PathVariable Integer id) {System.out.println(id);return "redirect:/user/listAll.do"; // 请求重定向}
访问的地址为:http://localhost:8080/day63_SpringMVC_02/user/updateByIdRestfull/1.do
(2)最终Restfull风格设计模式修改
约定:在web.xml配置拦截方式:在rest目录下所有请求都被拦截,servlet可以拦截目录。
web.xml中配置代码如下:
<servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/rest/*</url-pattern></servlet-mapping>
页面的代码:
<td><a href="${pageContext.request.contextPath}/rest/user/updateByIdRestfull/${user.id}">修改</a> </td>
接受参数的方法:
// 最终Restfull模式修改@RequestMapping("updateByIdRestfull/{id}")public String updateByIdRestfull(@PathVariable Integer id) {System.out.println(id);return "redirect:/user/listAll.do"; // 请求重定向}
访问的地址为:http://localhost:8080/day63_SpringMVC_02/rest/user/updateByIdRestfull/1
其中:
{id}:表示匹配接受页面url路径中的参数
@PathVariable:表示{id}里面参数注入后面参数id里面
url模版映射需要@RequestMapping和@PathVariable结合使用。
画图理解URL模版映射,如下图所示:
11.3、在线安装eclipse提示插件--Spring tools suite
步骤:Help --> Eclipse Marketplace… --> 在Find中输入Spring tools suite,点击安装即可。
安装成功后的截图如下:
12、转发和重定向
12.1、转发
- 本类中进行转发:本类中方法与方法之间进行forward
- 关键字:forward
- 转发方式一:return "forward:listAll.do";
- 转发方式二:return "/user/forward:listAll.do";
- 注意:`user根路径前面必须有/。`
- 跨类进行转发:
- 转发方式:return "forward:/items/listAll.do";
测试代码如下:
// 测试forward@RequestMapping("forward")public String forward() {// return "forward:listAll.do"; // 本类中转发方式一// return "/user/forward:listAll.do"; // 本类中转发方式二return "forward:/items/listAll.do"; // 跨类进行转发}
12.2、重定向
- 本类中进行重定向:本类中方法与方法之间进行redirect
- 关键字:redirect
- 重定向方式一:return "redirect:listAll.do";
- 重定向方式二:return "redirect:/user/listAll.do";
- 跨类进行重定向:
- 重定向方式:return "redirect:/items/listAll.do";
测试代码如下:
// 测试redirect@RequestMapping("redirect")public String redirect() {// return "redirect:listAll.do"; // 本类中重定向方式一// return "/user/redirect:listAll.do"; // 本类中重定向方式二return "redirect:/items/listAll.do"; // 跨类进行重定向}
13、标签< mvc:annotation-driven />的使用
详解如下:
标签<mvc:annotation-driven /> 表示默认创建处理器映射器RequestMappingHandlerMapping、处理器映射器RequestMappingHandlerAdapter,还表示默认启动json格式数据的支持。所以在springmvc.xml中就不要再配置处理器映射器和处理器映射器了。
只需要配置这一句就可以了。
14、RequestBody 和 ResponseBody
- @RequestBody 和 @ResponseBody,这两个注解主要是为了
提供对json格式数据的支持。
- @RequestBody的作用:把前台页面请求的json格式数据直接封装成JavaBean,使用ajax进行数据传递。
- @ResponseBody的作用:在后台,把JavaBean强制转换成json格式数据返回给前台页面。
这两个注解不能直接使用,需要依赖两个Jackson的jar包。
(1)先导入Jackson的jar包
(2)在springmvc.xml中配置json格式转换
注意:我们也可以直接使用<mvc:annotation-driven />
,因为该标签默认启动json格式数据的支持。
<!-- 配置注解的处理器适配器,作用:调用Controller方法,执行Controller --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><!-- 配置对json格式数据的支持 --><property name="messageConverters"><bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean></property></bean>
(3)请求json格式数据,返回json格式数据
(4)请求pojo格式数据,返回json格式数据
/day63_SpringMVC_02/WebRoot/WEB-INF/jsps/requestjson.jsp
前台代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<!-- 引入jquery.js的支持 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js"></script>
</head>
<body><input type="button" value="请求是json格式数据,返回是json格式数据" onclick="requestJson();"><br><input type="button" value="请求是pojo格式数据,返回是json格式数据" onclick="requestPojo();"><script type="text/javascript">function requestJson() {// 演示:构造一个json格式数据var jsonObj = JSON.stringify({'username':'晓艺','age':'26','address':'物资学院'}); // stringify的作用:把json格式的数据数强转成json对象// 发送ajax请求$.ajax({type:'post',url:'${pageContext.request.contextPath}/user/requestJson.do',contentType:'application/json;charset=UTF-8', // 默认: "application/x-www-form-urlencoded"data:jsonObj,success:function(data) { // 回调函数alert(data);}});}function requestPojo() {// 演示:构造一个pojo格式数据var pojoObj = 'username=黑泽&age=26&address=青年路';// 发送ajax请求$.ajax({type:'post',url:'${pageContext.request.contextPath}/user/requestPojo.do',data:pojoObj,success:function(data) { // 回调函数alert(data);}}); }</script>
</body>
</html>
后台代码:
// 跳转方法,跳转到requestjson.jsp页面@RequestMapping("toJson")public String tiJson() {return "requestjson";}// 接收json格式数据,使用 @RequestBody 把json格式数据封装进JavaBean对象中(本例中是User对象)// 返回json对象,使用 @ResponseBody 把User对象转换成json对象@RequestMapping("requestJson")public @ResponseBody User requestJson(@RequestBody User user) {System.out.println(user);return user;}// 接收pojo格式数据// 返回json对象,使用@ResponseBody 把User对象转换成json对象@RequestMapping("requestPojo")public @ResponseBody User requestPojo(User user) {System.out.println(user);return user;}
SpringMVC学习笔记_01相关推荐
- SpringMVC:学习笔记(11)——依赖注入与@Autowired
SpringMVC:学习笔记(11)--依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...
- SpringMVC:学习笔记(10)——整合Ckeditor且实现图片上传
SpringMVC:学习笔记(10)--整合Ckeditor且实现图片上传 配置CKEDITOR 精简文件 解压之后可以看到ckeditor/lang下面有很多语言的js,如果不需要那么多种语言的,可 ...
- springmvc学习笔记(10)-springmvc注解开发之商品改动功能
springmvc学习笔记(10)-springmvc注解开发之商品改动功能 springmvc学习笔记(10)-springmvc注解开发之商品改动功能 标签: springmvc springmv ...
- springmvc学习笔记(19)-RESTful支持
springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...
- SpringMVC:学习笔记(5)——数据绑定及表单标签
SpringMVC--数据绑定及表单标签 理解数据绑定 为什么要使用数据绑定 基于HTTP特性,所有的用户输入的请求参数类型都是String,比如下面表单: 按照我们以往所学,如果要获取请求的所有参数 ...
- springmvc学习笔记(17)-上传图片
2019独角兽企业重金招聘Python工程师标准>>> springmvc学习笔记(17)-上传图片 标签: springmvc [TOC] 本文展示如何在springmvc中上传图 ...
- SpringMVC学习笔记(二)常用注解
SpringMVC学习笔记(二)常用注解 1.RequestParam 作用: 把请求中指定名称的参数给控制器中的形参赋值. 属性: value:请求参数中的名称. required:请求参数中是否必 ...
- springmvc学习笔记--ueditor和springmvc的集成
springmvc学习笔记--ueditor和springmvc的集成 前言: 在web开发中, 富文本的编辑器真心很重要. 有电商店铺的打理, 新闻稿/博客文章/论坛帖子的编辑等等, 这种所见即所的 ...
- SpringMVC学习笔记
文章目录 SpringMVC学习笔记 Spring MVC 什么是 MVC 设计模式? Spring MVC 的核心组件 Spring MVC 的工作流程 如何使用? Spring MVC 注解 Sp ...
最新文章
- 做操作系统的公司,为什么不能把系统安全做好?
- Java描述设计模式(20):命令模式
- Flutter WillPopScope 双击返回与界面退出提示
- php 判断昨天_PHP 判断时间在今天、昨天、前天、几天前几点
- KVM halt-polling机制分析
- ArcGIS栅格数据批量转换格式
- Go 爱好者福利,《Go 语言编程之旅》正式开源!
- 【毫米波雷达】人体目标探测理论
- MapGIS6.7投影生成点-以物化探综合剖面图为例
- VS2010中自制8*8字模提取
- 操作系统添加系统调用+内核编译
- java软连接_硬链接和软连接
- takes 1 positional argument but 2 were given
- Cloud Compare快速大规模配准
- 输入数字怎么变成大写python_Python将阿拉伯数字转化为中文大写
- linux下firebox的flash插件
- Python基础(二) 基本数据类型①:整数型、布尔型、字符串
- 密码学篇(数据完整性)
- Springboot毕设项目地方特色美食小吃分享平台6iqqq(java+VUE+Mybatis+Maven+Mysql)
- php 表格生成word,PHP生成WORD表格