day63_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);
}
@Override
protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command,
BindException errors) throws Exception {
// 参数被封装进命令对象,这个过程很复杂,我们暂时不用管它,只要知道它使用的是命令设计模式即可
// 把命令对象强转成User对象
User user = (User) command;
// 设置Model的数据,值可以是任意pojo
ModelAndView 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);
}
@Override
protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
// 参数被封装进命令对象,这个过程很复杂,我们暂时不用管它,只要知道它使用的是命令设计模式即可
// 把命令对象强转成User对象
User user = (User) command;
// 设置Model的数据,值可以是任意pojo
ModelAndView mv = new ModelAndView();
mv.addObject("user", user);
// 指定返回页面
mv.setViewName("index");
return mv;
}
@Override
protected 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.do
public String myHello() {
// 表示springmvc返回了一个逻辑视图hello.jsp
return "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.jsp
return "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;
}
@Override
public 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、ActionSupport、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;
}
day63_SpringMVC学习笔记_01的更多相关文章
- Lua的热更新学习笔记_01
热更新的的实现方式 1.使用lua脚本编写游戏的UI或者其他的逻辑 2.使用C#的反射技术 3.使用C#Light AssetBundle是什么? 1.unity提供一个资源更新技术,就是通过Asse ...
- day42_Oracle学习笔记_01
一.Oracle Database 的基本概念 1.1.一个Oracle服务器 详解如下: 一个Oracle服务器是一个关系型数据管理系统(RDBMS),它提供开放的,全面的,近乎完整的信息管理. ...
- jQuery 学习笔记_01
jQuery是一个简洁快速灵活的JavaScript框架,能让你在网页上简单的操作文档.处理事件.实现特效并为Web页面添加Ajax交互. 1 jQuery大多是基于 document 一个或多个元素 ...
- SASS学习笔记_01
scss两种格式 sass 大括号 scss css写法 Arguments: --no-cache –style compressed --update $FileName$:c ...
- React学习笔记_01
使用Facebook的create-react-app快速构建React开发环境 前言: create-react-app:来自Facebook官方的零配置命令行工具 create-react-app ...
- SpringMVC学习笔记_01
1.JAVAEE体系结构 JAVAEE体系结构图如下所示: 2.什么是springmvc? 什么是mvc? Model1 Model2 SpringMVC是什么? SpringMVC是一个web层mv ...
- node学习笔记_01 环境搭建
一.下载安装nvm (node版本管理器),方便以后版本切换 nvm list -> 查看node版本(版本最好在8.0以上,不然在vsCode断点调试进不去,跟node版 ...
- Python学习笔记_01:基本概念介绍
目录 1.Python语言简介 2.Python中常用数据结构 2.1什么是列表? 2.2什么是元组? 2.3什么是字典? 2.4索引及分片 3.其它基本概念 3.1数据类型和变量 3.2生成器 3. ...
- jQuery源代码学习笔记_01
如何获取jQuery源代码 1.可以从GitHub上下载到没有合并和压缩的源代码 2.如果要查看兼容IE6-8的版本,请选择1.x-master分支 3.可以使用git clone也可以使用downl ...
随机推荐
- 我的小游戏上线海外AppStore完整流程心得
1,购买一台Mac或者用VMWare 安装Mac OS流程,笔者使用VMWare. 先安装Mac OS 10.13,教程,成功后不要着急安装vmtools, 首先更新系统至最新版,因为真机测试往往需要 ...
- 浅谈我的UI设计之路
时光匆匆,进入UI学习已经快两个月了,这段时间过得很充实,因为有压力才有收获. 还记的刚刚学习手绘的时候,对于这个行业只有一个初步的认识,知道自己喜欢,但是真正学习的时候才发现,我要学习的东西还有很多 ...
- 金蝶盘点机PDA仓库条码管理家电类序列号扫描操作方法-采购入库单
1.1. 采购入库单 传统的进销存管理软件需要人工识别商品品种,清点商品数量,然后再去人工手工在电脑上一行行的录入采购入库单.录单效率低,误差大. 如果使用汉码盘点机PDA,入库时,仓管员只需要手持 ...
- Hexo初体验
title: Hexo初体验 date: 2018-05-10 tags: Hexo categories: Hexo --- Hexo本地安装 Node.js安装 Hexo npm安装如下 npm ...
- Linux内核分析作业 NO.5
拔掉系统调用的三层皮(下) 于佳心 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...
- Linux内核分析——第一周学习笔记
20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 第一节 存储程序计算机工作模型 1.冯诺依曼体系结构:即具有存储程序的计算机体系结构.目前大多数拥有计算和存储功能的设备(智能 ...
- windows 64bit 服务器下安装32位oracle database 11g 问题集
1.中文乱码 问题描述: 利用vs2008调试的时候正常,发布到IIS8.5上的时候,当查询语句中包含中文的时候会乱码,比如"select * from tb where name='小s' ...
- DeepID人脸识别算法之三代
DeepID人脸识别算法之三代 转载请注明:http://blog.csdn.net/stdcoutzyx/article/details/42091205 DeepID,眼下最强人脸识别算法.已经三 ...
- springboot项目的创建
创建springboot项目 包名和项目名 选择需要使用的框架,web 然后再点击下一步,完成即可创建springboot项目
- 使用maven的插件进行maven项目的打包
1 maven项目打包的插件有3种 maven-jar-plugin maven-assembly-plugin maven-shade-plugin 2 maven-jar-plugin 现在要新增 ...