SpringMVC学习笔记_01

1、JAVAEE体系结构

  • JAVAEE体系结构图如下所示:

2、什么是springmvc?

  • 什么是mvc?

    • Model1
    • Model2
  • 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执行流程(运行原理),如下图所示:

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等等。
      • 方法的参数属于局部变量,存活时间短。
  • 参数封装来分析:
    • 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相关推荐

  1. SpringMVC:学习笔记(11)——依赖注入与@Autowired

    SpringMVC:学习笔记(11)--依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...

  2. SpringMVC:学习笔记(10)——整合Ckeditor且实现图片上传

    SpringMVC:学习笔记(10)--整合Ckeditor且实现图片上传 配置CKEDITOR 精简文件 解压之后可以看到ckeditor/lang下面有很多语言的js,如果不需要那么多种语言的,可 ...

  3. springmvc学习笔记(10)-springmvc注解开发之商品改动功能

    springmvc学习笔记(10)-springmvc注解开发之商品改动功能 springmvc学习笔记(10)-springmvc注解开发之商品改动功能 标签: springmvc springmv ...

  4. springmvc学习笔记(19)-RESTful支持

    springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...

  5. SpringMVC:学习笔记(5)——数据绑定及表单标签

    SpringMVC--数据绑定及表单标签 理解数据绑定 为什么要使用数据绑定 基于HTTP特性,所有的用户输入的请求参数类型都是String,比如下面表单: 按照我们以往所学,如果要获取请求的所有参数 ...

  6. springmvc学习笔记(17)-上传图片

    2019独角兽企业重金招聘Python工程师标准>>> springmvc学习笔记(17)-上传图片 标签: springmvc [TOC] 本文展示如何在springmvc中上传图 ...

  7. SpringMVC学习笔记(二)常用注解

    SpringMVC学习笔记(二)常用注解 1.RequestParam 作用: 把请求中指定名称的参数给控制器中的形参赋值. 属性: value:请求参数中的名称. required:请求参数中是否必 ...

  8. springmvc学习笔记--ueditor和springmvc的集成

    springmvc学习笔记--ueditor和springmvc的集成 前言: 在web开发中, 富文本的编辑器真心很重要. 有电商店铺的打理, 新闻稿/博客文章/论坛帖子的编辑等等, 这种所见即所的 ...

  9. SpringMVC学习笔记

    文章目录 SpringMVC学习笔记 Spring MVC 什么是 MVC 设计模式? Spring MVC 的核心组件 Spring MVC 的工作流程 如何使用? Spring MVC 注解 Sp ...

最新文章

  1. 做操作系统的公司,为什么不能把系统安全做好?
  2. Java描述设计模式(20):命令模式
  3. Flutter WillPopScope 双击返回与界面退出提示
  4. php 判断昨天_PHP 判断时间在今天、昨天、前天、几天前几点
  5. KVM halt-polling机制分析
  6. ArcGIS栅格数据批量转换格式
  7. Go 爱好者福利,《Go 语言编程之旅》正式开源!
  8. 【毫米波雷达】人体目标探测理论
  9. MapGIS6.7投影生成点-以物化探综合剖面图为例
  10. VS2010中自制8*8字模提取
  11. 操作系统添加系统调用+内核编译
  12. java软连接_硬链接和软连接
  13. takes 1 positional argument but 2 were given
  14. Cloud Compare快速大规模配准
  15. 输入数字怎么变成大写python_Python将阿拉伯数字转化为中文大写
  16. linux下firebox的flash插件
  17. Python基础(二) 基本数据类型①:整数型、布尔型、字符串
  18. 密码学篇(数据完整性)
  19. Springboot毕设项目地方特色美食小吃分享平台6iqqq(java+VUE+Mybatis+Maven+Mysql)
  20. php 表格生成word,PHP生成WORD表格

热门文章

  1. 2021-08-02 Linux — 初始化服务器练习
  2. 一只特立独行的猪-王小波作品
  3. 通信标准10之CSI参考信号
  4. KNN算法学习-实现海伦约会网站与手写体识别实验
  5. 马里奥追踪算法Tracking
  6. Shiro 中的 Realm
  7. 10-数组--highgh的博客--JavaScript的学习笔记
  8. 记一次 .NET 某医院门诊软件 卡死分析
  9. iframe在IE中的透明问题与allowTransparency属性
  10. 由浅入深,带你玩转几种常用java设计模式