前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day63_SpringMVC学习笔记_01

day63_SpringMVC学习笔记_01

作者头像
黑泽君
发布2018-11-29 18:22:25
7000
发布2018-11-29 18:22:25
举报
文章被收录于专栏:黑泽君的专栏黑泽君的专栏

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、不使用视图解析器+使用视图解析器

(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(入口)

代码语言:javascript
复制
????<!--?配置前端控制器: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

代码语言:javascript
复制
<?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>

????<!--?配置视图解析器,InternalResourceViewResolver负责解析出真正的逻辑视图?-->
????<!--?后台返回逻辑视图:index
????????视图解析器解析出真正的物理视图:前缀+逻辑视图+后缀?==>/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)

代码语言:javascript
复制
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

代码语言:javascript
复制
<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)自定义命令控制器

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
<%@?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

代码语言:javascript
复制
<%@?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来访问。

代码语言:javascript
复制
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

代码语言:javascript
复制
????<!--?配置自定义的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编码过滤器,如下所示:

代码语言:javascript
复制
????<!--?配置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()方法,示例代码如下:

代码语言:javascript
复制
//?从页面接收参数,封装到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文件:配置处理器映射器、配置处理器适配器、配置视图解析器
    • 自定义Controller类,使用注解开发:添加,返回到成功页面进行回显,点击修改回到添加页面,初步理解参数传递。

(1)创建一个动态的web工程,导入jar文件 ??详细过程同3、springmvc第一个程序案例 (2)配置web.xml

代码语言:javascript
复制
<?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管理、配置处理器映射器、配置处理器适配器、配置视图解析器

代码语言:javascript
复制
<?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>

????<!--?配置视图解析器,InternalResourceViewResolver负责解析出真正的逻辑视图?-->
????<!--?后台返回逻辑视图:index,?视图解析器解析出真正的物理视图:前缀+逻辑视图+后缀?==>/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类

代码语言:javascript
复制
@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

代码语言:javascript
复制
<%@?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

功能:请求映射

代码语言:javascript
复制
几种写法:
????@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的根路径

代码语言:javascript
复制
@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

演示:自定义根路径

代码语言:javascript
复制
@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:默认值,表示如果请求中没有同名参数时的默认值。 示例如下:

代码语言:javascript
复制
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没有成员变量,那页面提交过来的参数该如何接收和进行传递呢?
  • 答:把需要传递的参数对象放入方法里面,当你请求这个方法,向这个方法传递参数的时候,这个方法里面的对象会自动被创建,需要的参数会自动被封装到方法的对象里面。

分析接受参数类型:

代码语言:javascript
复制
基本类型
????int、String等基本类型。
Pojo类型
包装类型
集合类型

Springmvc默认支持类型:
????HttpSession、HttpRequstServlet、Model等等。

Struts2参数封装:基于属性驱动封装。
Springmvc参数封装:基于方法进行封装。

9.1、封装int类型参数

  • 页面传递的参数都是字符串。

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收int类型参数?
????@RequestMapping("recieveInt")
????public?String?recieveInt(Integer?id)?{
????????System.out.println(id);
????????return?"success";
????}
  • 注意:标签input的name的属性值id要与方法的形式参数名称id相同。

9.2、封装String类型参数

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收String类型参数?
????@RequestMapping("recieveString")
????public?String?recieveString(String?username)?{
????????System.out.println(username);
????????return?"success";
????}

9.3、封装数组类型参数

  • 分析:封装数组是批量删除时使用,使用checkbox复选框,其value属性必须有值。

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收数组类型参数?
????@RequestMapping("recieveArray")
????public?String?recieveArray(Integer[]?ids)?{
????????System.out.println(ids);
????????return?"success";
????}

9.4、封装pojo类型参数

创建一个pojo类:

代码语言:javascript
复制
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?+?"]";
????}
}

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收pojo类型参数?
????@RequestMapping("recieveUser")
????public?String?recieveString(User?user)?{
????????System.out.println(user);
????????return?"success";
????}

9.4、封装包装类型参数

创建一个包装类:

代码语言:javascript
复制
public?class?UserCustom?{

????private?User?user;

????public?User?getUser()?{
????????return?user;
????}

????public?void?setUser(User?user)?{
????????this.user?=?user;
????}
}

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收包装类型参数?
????@RequestMapping("recieveUserCustom")
????public?String?recieveUserCustom(UserCustom?userCustom)?{
????????System.out.println(userCustom);
????????return?"success";
????}

9.5、封装集合类型参数

9.5.1、封装List集合类型参数
  • 注意:不能直接传递集合类型,需要把集合类型封装到包装类中。

我们先把List集合封装到包装类中。即:在包装类中定义List集合。提供getter和setter方法。

代码语言:javascript
复制
????private?List<User>?userList;

????public?List<User>?getUserList()?{
????????return?userList;
????}

????public?void?setUserList(List<User>?userList)?{
????????this.userList?=?userList;
????}

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收List结合类型参数?
????@RequestMapping("recieveList")
????public?String?recieveList(UserCustom?userCustom)?{
????????System.out.println(userCustom);
????????return?"success";
????}
9.5.2、封装Map集合类型参数

我们先把Map集合封装到包装类中。即:在包装类中定义Map集合。提供getter和setter方法。

代码语言:javascript
复制
????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;
????}

页面的代码:

代码语言:javascript
复制
????<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>

接受参数的方法:

代码语言:javascript
复制
????//?接收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、查询所有

页面的代码:

代码语言:javascript
复制
<%@?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>

接受参数的方法:

代码语言:javascript
复制
????//?查询所有
????@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、普通模式修改

页面的代码:

代码语言:javascript
复制
????<td>
????????<a?href="${pageContext.request.contextPath}/user/updateByIdNormal.do?id=${user.id}">修改</a>
????</td>

接受参数的方法:

代码语言:javascript
复制
????//?普通模式修改
????@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风格设计模式修改 页面的代码:

代码语言:javascript
复制
????<td>
????????<a?href="${pageContext.request.contextPath}/user/updateByIdRestfull/${user.id}.do">修改</a>?<!--?把参数放在了请求的里面了?-->
????</td>

接受参数的方法:

代码语言:javascript
复制
????//?初始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中配置代码如下:

代码语言:javascript
复制
????<servlet-mapping>
????????<servlet-name>springmvc</servlet-name>
????????<url-pattern>/rest/*</url-pattern>
????</servlet-mapping>

页面的代码:

代码语言:javascript
复制
????<td>
????????<a?href="${pageContext.request.contextPath}/rest/user/updateByIdRestfull/${user.id}">修改</a>?
????</td>

接受参数的方法:

代码语言:javascript
复制
????//?最终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路径中的参数 ??@Pathariable:表示{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";

测试代码如下:

代码语言:javascript
复制
????//?测试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";

测试代码如下:

代码语言:javascript
复制
????//?测试redirect
????@RequestMapping("redirect")
????public?String?redirect()?{
????????//?return?"redirect:listAll.do";?//?本类中重定向方式一
????????//?return?"/user/redirect:listAll.do";?//?本类中重定向方式二
????????return?"redirect:/items/listAll.do";?//?跨类进行重定向
????}

13、标签<mvc:annotation-driven />的使用

详解如下:

代码语言:javascript
复制
标签<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格式数据的支持。

代码语言:javascript
复制
????<!--?配置注解的处理器适配器,作用:调用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 前台代码:

代码语言:javascript
复制
<%@?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>

后台代码:

代码语言:javascript
复制
????//?跳转方法,跳转到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;
????}
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、JAVAEE体系结构
  • 2、什么是springmvc?
  • 3、springmvc第一个程序案例
    • 3.1、不使用视图解析器+使用视图解析器
    • 4、根据程序分析springmvc执行流程(画图)
    • 5、处理器映射器
      • 5.1、配置默认处理器映射器(BeanNameUrlHandlerMapping)
        • 5.2、配置集中处理器映射器(SimpleHandlerMapping)
          • 5.3、配置类名处理器映射器(ClassNameHandlerMapping)
          • 6、处理器适配器
            • 6.1、配置默认处理器适配器(SimpleControllerHandlerAdapt)
              • 6.2、配置请求处理器适配器(HttpRequestHandlerAdapter)
              • 7、命令控制器
                • 7.1、Controller简介
                  • 7.2、演示:自定义命令控制器
                    • 7.3、中文乱码解决
                      • 7.4、时间类型转换
                        • 7.5、参数控制器ParameterizableViewController
                        • 8、注解开发
                          • 8.1、注解开发第一个入门程序
                            • 8.2、注解开发流程图
                              • 8.3、RequestMapping
                                • 8.4、RequestMapping的根路径
                                  • 8.5、RequestParam
                                  • 9、封装参数
                                    • 9.1、封装int类型参数
                                      • 9.2、封装String类型参数
                                        • 9.3、封装数组类型参数
                                          • 9.4、封装pojo类型参数
                                            • 9.4、封装包装类型参数
                                              • 9.5、封装集合类型参数
                                                • 9.5.1、封装List集合类型参数
                                                • 9.5.2、封装Map集合类型参数
                                              • 9.6、思考:有了struts2,为什么还需要sprigmvc呢?
                                              • 10、页面回显
                                                • 10.1、查询所有
                                                • 11、URL模版映射
                                                  • 11.1、普通模式修改
                                                    • 11.2、Restfull风格设计模式修改
                                                      • 11.3、在线安装eclipse提示插件--Spring tools suite
                                                      • 12、转发和重定向
                                                        • 12.1、转发
                                                          • 12.2、重定向
                                                          • 13、标签<mvc:annotation-driven />的使用
                                                          • 14、RequestBody 和 ResponseBody
                                                          领券
                                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                                                          http://www.vxiaotou.com