任务一: SpringMVC基本应用
课程任务主要内容:
* SpringMVC简介
* SpringMVC组件概述
* SpringMVC请求
* SpringMVC响应
* 静态资源开启
一 SpringMVC简介
1.1 MVC模式
MVC是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想。
* M(model)模型:处理业务逻辑,封装实体
* V(view) 视图:展示内容
* C(controller)控制器:负责调度分发(1.接收请求、2.调用模型、3.转发到视图)
1.2 SpringMVC概述
SpringMVC 是一种基于 Java 的实现 MVC 设计模式的轻量级 Web 框架,属于SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 中。
SpringMVC 已经成为目前最主流的MVC框架之一,并且随着Spring3.0 的发布,全面超越 Struts2,*成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。
总结
SpringMVC的框架就是封装了原来Servlet中的共有行为;例如:参数封装,视图转发等。(封装共有行为就相当于之前使用BaseServlet一样)
1.3 SpringMVC快速入门
需求
客户端发起请求,服务器接收请求,执行逻辑并进行视图跳转。
步骤分析
1. 创建web项目,导入SpringMVC相关坐标
2. 配置SpringMVC前端控制器 DispathcerServlet
3. 编写Controller类和视图页面
4. 使用注解配置Controller类中业务方法的映射地址
5. 配置SpringMVC核心文件 spring-mvc.xml
1)创建web项目springMVC_quickStart,导入SpringMVC相关坐标
pom.xml
<!--指定编码和版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.11</java.version>
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
</properties>
<!-- 设置为web工程 -->
<packaging>war</packaging>
<dependencies>
<!--springMVC坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!--servlet坐标-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp坐标-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
2)配置SpringMVC前端控制器DispathcerServlet
在web.xml文件中配置前端控制器的servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置springMVC的前端控制器:DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<!--借助DispatcherServlet来加载spring-mvc的核心配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--要求在启动应用时,就完成servlet的实例化及初始化操作-->
<load-on-startup>2</load-on-startup>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--/斜杠表示会匹配到所有的访问路径,但是不会匹配到像*.jsp这样的带有后缀名的访问url路径-->
<!--/*表示可以匹配到所有的访问路径,不管有没有后缀名-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3)编写Controller类和视图页面
controller类
public class UserController {
public String quick(){
/*业务逻辑*/
System.out.println("SpringMVC日美成功。。。");
/*视图跳转*/
return "/WEB-INF/pages/success.jsp";
}
}
跳转视图jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>springMVC入门初体验</title>
</head>
<body>
<h3>springMVC入门初体验</h3>
</body>
</html>
4)使用注解配置Controller类中业务方法的映射地址
给controller类加上相应的注解
@Controller
public class UserController {
@RequestMapping("/quick")//配置范围地址
public String quick(){
/*业务逻辑*/
System.out.println("SpringMVC日美成功。。。");
/*视图跳转*/
return "/WEB-INF/pages/success.jsp";
}
}
5)配置SpringMVC核心文件spring-mvc.xml
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置注解扫描-->
<context:component-scan base-package="com.myLagou.controller"/>
</beans>
1.4 web工程执行流程
1.5 知识小结
-
SpringMVC是对MVC设计模式的一种实现,属于轻量级的WEB框架7。
-
SpringMVC的开发步骤:
- 1.创建web项目,导入SpringMVC相关坐标
- 2.配置SpringMVC前端控制器 DispathcerServlet
- 3.编写Controller类和视图页面
- 4.使用注解配置Controller类中业务方法的映射地址
- 5.配置SpringMVC核心文件 spring-mvc.xml
二 SpringMVC组件概述
2.1 SpringMVC的执行流程
1. 用户发送请求至前端控制器DispatcherServlet。
2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4. DispatcherServlet调用HandlerAdapter处理器适配器。
5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6. Controller执行完成返回ModelAndView。
7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9. ViewReslover解析后返回具体View。
10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11. DispatcherServlet将渲染后的视图响应响应用户。
2.2 SpringMVC组件解析
- 1、前端控制器:DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的 中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
- 2、处理器映射器:HandlerMapping
HandlerMapping 负责根据用户请求找到 Handler 即处理器(也就是编写的Controller),SpringMVC 提供了不同的映射器 实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
- 3、处理器适配器:HandlerAdapter
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型 的处理器进行执行。
- 4、处理器:Handler【开发者编写的Controller】
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
- 5、视图解析器:ViewResolver
View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物 理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给 用户。
- 6、视图:View 【开发者编写】
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、 pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展 示给用户,需要由程序员根据业务需求开发具体的页面。
***笔试题:springmvc中的三大组件是什么?
1、处理器映射器 2、处理器适配器 3、视图解析器
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置注解扫描-->
<context:component-scan base-package="com.myLagou.controller"/>
<!--使用mvc开头的标签需要在上面进行引入相应的包-->
<!--配置处理器映射器和处理器适配器-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--<mvc:annotation-driven>这一个标签同时配置了处理器映射器和处理器适配器-->
<!--使用这一个标签二不分开配置的原因:
1、一个标签的效率比分开配置高;
2、这个标签对处理器映射器和处理器适配器进行了功能加强:支持json的读写
-->
<!--配置视图解析器:ViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置视图的前后缀-->
<property name="prefix" value="/WEB-INF/pages/"></property><!--前缀-->
<property name="suffix" value=".jsp"></property><!--后缀-->
</bean>
</beans>
2.3 SpringMVC注解解析
@Controller
SpringMVC基于Spring容器,所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中,如果使用@Controller注解标注的话,就需要使用:
<!--配置注解扫描-->
<context:component-scan base-package="com.myLagou.controller"/>
==注意:==当spring与springMVC整合时,spring的ioc容器为父容器,spring-mvc的为子容器
@RequestMapping
- 作用:用于建立请求 URL 和处理请求方法之间的对应关系
- 位置:
- 1.类上:请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/开头。
- 它出现的目的是为了使我们的URL可以按照模块化管理,以便区分:
- 用户模块
- /user/add
- /user/update
- /user/delete
- …
- 账户模块
- /account/add
- /account/update
- /account/delete
- 用户模块
- 2.方法上:请求URL的第二级访问目录,和一级目录组成一个完整的 URL 路径。
- 属性:
- 1.value:用于指定请求的URL。它和path属性的作用是一样的 ,当只有一个value属性的时候,value就可以省略不写
- 2.method:用来限定请求的方式
- 3.params:用来限定请求参数的条件
- 例如:params={“accountName”} 表示请求参数中必须有accountName
- pramss={“money!100”} 表示请求参数中money不能是100
- @RequestMapping注解的params属性是一个字符串类型的数组,可以通过四种表达式设置请求参数和请求映射的匹配关系
- "param”:要求请求映射所匹配的请求必须携带param请求参数,例如username
- "!param”:要求请求映射所匹配的请求必须不能携带param请求参数,例如!username
- “param=value”:要求请求映射所匹配的请求必须携带param请求参数且param=value,例如username=admin
- “param!=value”:要求请求映射所匹配的请求必须携带param请求参数但是param!=value,例如password!=123456
代码示例
@Controller
//@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
//@RequestMapping注解使用在类上就是二级访问目录,当一级与二级都同时存在时,需要一级一级的访问,先写一级再写二级
@RequestMapping(path = "/quick", method = RequestMethod.GET, params={"accountName","money!=100"})//配置范围地址
/*1.value:用于指定请求的URL。它和path属性的作用是一样的,都是设置方法的映射地址
* 2.method:用来限定请求的方式,设置了值之后只能通过设置的请求方式访问该路径,其他的请求方式都会导致报错
* 3.params:用来限定请求参数的条件 params = {"accountName"}表示请求中必须带有参数accountName,否则都会报错
* params={"money!=100"} 表示请求参数中money不能是100
* */
public String quick(String accountName, Double money){
/*业务逻辑*/
System.out.println("SpringMVC入门成功。。。");
/*视图跳转*/ //通过请求转发
// return "/WEB-INF/pages/success.jsp";//在没有配置视图解析器时需要写全路径
return "success";//在spring-mvc.xml文件中配置了视图解析器之后只需要写逻辑视图名,在真正解析时会
//拼接为具体的物理文件地址
}
}
2.4 知识小结
-
SpringMVC的三大组件
- 处理器映射器:HandlerMapping
- 处理器适配器:HandlerAdapter
- 视图解析器:View Resolver
- 如果问的是四大组件的话就再加上前端控制器DispacherServlet
-
开发者编写
- 处理器:Handler
- 视图:View
三 SpringMVC的请求
3.1 请求参数类型介绍
客户端请求参数的格式是: name=value&name=value…… (参数的值皆为String类型,所以需要类型转换)
服务器要获取请求的参数的时候要进行类型转换,有时还需要进行数据的封装
SpringMVC可以接收如下类型的参数:
- 基本类型参数
- 对象类型参数
- 数组类型参数
- 集合类型参数
3.2 获取基本类型参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;自动的类型转换是指从String向其他类型的转换。
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试请求参数类型</title>
</head>
<body>
<h1>请求参数类型为基本数据类型</h1>
<%--${pageContext.request.contextPath}表示使用el表达式动态获取当前项目的路径--%>
<a href="${pageContext.request.contextPath}/user/simpleParam?id=1&username=杰克">
基本数据类型参数
</a>
</body>
</html>
注意:如果前端页面是放在WEB-INF目录下的,则不允许在浏览器的地址栏直接访问,因为WEB-INF是一个安全目录,不会允许这样直接访问操作,需要借助请求转发
UserController下的simpleParam方法
@RequestMapping("/simpleParam")
public String simpleParam(Integer id, String username){
System.out.println(id);
System.out.println(username);
return "success";
}
3.3 获取对象类型参数
Controller中的业务方法参数的POJO属性名与请求参数的name一致,springmvc会自动调用POJO类的set方法使参数值会自动映射匹配。
注意:在tomcat 8.5以上版本,tomcat已经自动解决get请求的中文乱码问题,而没有解决post请求的中文乱码问题,需要自己解决
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试请求参数类型</title>
</head>
<body>
<h3>请求参数类型为对象类型</h3>
<form action="${pageContext.request.contextPath}/user/pojoParam" method="post">
编号:<input type="text" name="id">
用户名:<input type="text" name="username">
<input type="submit" value="对象类型参数">
</form>
</body>
</html>
User实体类
public class User {
private Integer id;
private String username;
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
'}';
}
}
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
@RequestMapping("/pojoParam")
public String pojoParam(User user){
System.out.println(user);
return "success";
}
}
3.4 中文乱码过滤器
当post请求时,数据会出现乱码,我们可以在web.xml文件中设置一个过滤器来进行编码的过滤。
<!--中文乱码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.5 获取数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试请求参数类型</title>
</head>
<body>
<h3>请求参数类型为数组类型</h3>
<form method="post" action="${pageContext.request.contextPath}/user/arrayParam">
编号:<br>
<input type="checkbox" name="ids" value="1">1<br>
<input type="checkbox" name="ids" value="2">2<br>
<input type="checkbox" name="ids" value="3">3<br>
<input type="checkbox" name="ids" value="4">4<br>
<%--选择复选框时,实际向后台传递的参数值为value中的值--%>
<input type="submit" value="数组类型参数">
</form>
</body>
</html>
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*获取数组类型的请求参数*/
@RequestMapping("/arrayParam")
public String arrayParam(Integer[] ids){
System.out.println(Arrays.toString(ids));
return "success";
}
}
3.6 获取集合(复杂)类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以。
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试请求参数类型</title>
</head>
<body>
<h3>请求参数类型为集合类型</h3>
<form method="post" action="${pageContext.request.contextPath}/user/queryParam">
搜索关键字:<br><input type="text" name="keyword"><br>
<hr><br>
user对象:<br>
<input type="text" name="user.id" placeholder="编号"><br>
<input type="text" name="user.username" placeholder="姓名">
<hr><br>
list集合:<br>
第一个元素:<br>
<input type="text" name="userList[0].id" placeholder="编号"><br>
<input type="text" name="userList[0].username" placeholder="姓名"><br><br>
第二个元素:<br>
<input type="text" name="userList[1].id" placeholder="编号"><br>
<input type="text" name="userList[2].username" placeholder="姓名"><br>
<hr><br>
map集合:<br>
第一个元素:<br>
<input type="text" name="userMap['u1'].id" placeholder="编号"><br>
<input type="text" name="userMap['u1'].username" placeholder="姓名"><br><br>
第二个元素:<br>
<input type="text" name="userMap['u2'].id" placeholder="编号"><br>
<input type="text" name="userMap['u2'].username" placeholder="姓名"><br>
<input type="submit" value="获取集合类型参数">
</form>
</body>
</html>
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*获取集合(复杂)类型的请求参数*/
@RequestMapping("/queryParam")
public String queryParam(QueryVo queryVo){
System.out.println(queryVo);
return "success";
}
}
3.7 自定义类型转换器
SpringMVC 默认已经提供了一些常用的类型转换器;例如:客户端提交的字符串转换成int型进行参数设置,日期格式类型要求为:yyyy/MM/dd 不然的话会报错,对于特有的行为,SpringMVC提供了自定义类型转换器方便开发者自定义处理。
错误请求演示
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试请求参数类型</title>
</head>
<body>
<%--演示自动类型转换器因日期格式问题而产生的错误 正确的日期格式类型要求为:yyyy/MM/dd--%>
<form action="${pageContext.request.contextPath}/user/converter" method="post">
生日:<input type="text" name="birthday">
<input type="submit" value="类型转换器错误演示">
<%--只能通过yyyy/MM/dd这个格式的日期请求,其他格式的请求都会报错--%>
</form>
</body>
</html>
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*测试自动类型转换器的错误产生*/
@RequestMapping("/converter")
public String converter(Date birthday){
System.out.println(birthday);
return "success";
}
}
结果
完成自定义转换器
requestParam.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title></title>
</head>
<body>
<%--演示自定义类型转换器,自定义日期格式类型要求为:yyyy-MM-dd--%>
<form action="${pageContext.request.contextPath}/user/converter" method="post">
生日:<input type="text" name="birthday">
<input type="submit" value="自定义类型转换器演示">
<%--只能通过yyyy/MM/dd这个格式的日期请求,其他格式的请求都会报错--%>
</form>
</body>
</html>
编写自定义类型转换器类DateConverter
/*自定义类型转换器*/
public class DateConverter implements Converter<String, Date> {
@Override
/*s就是从表单传递过来的请求参数*/
public Date convert(String s) {
//将日期字符串转换为日期对象,并返回
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
在spring-mvc.xml配置文件中配置自定义类型转换器
<!--添加了自定义类型转换器-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
<!--如果只是单纯的进行了下面的配置,自定义类型转换器是不能生效的,需要在上述标签中添加conversion-service属性才可以生效-->
<!--自定义类型转换器的配置-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.myLagou.converter.DateConverter"></bean>
</set>
</property>
</bean>
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*测试自定义类型转换器*/
@RequestMapping("/converter")
public String converter(Date birthday){
System.out.println(birthday);
return "success";
}
}
3.8 相关注解
@RequestParam
当请求的参数name名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解显示的绑定
<%--演示@RequestParam注解--%>
<a href="${pageContext.request.contextPath}/user/findByPage?pageNo=2">
分页查询
</a>
Controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*演示@RequestParam注解*/
@RequestMapping("/findByPage")
public String findByPage(@RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNum,
@RequestParam(defaultValue = "5") Integer pageSize){
/* @RequestParam() 注解的参数详解
defaultValue 设置参数默认值
name 匹配页面传递参数的名称
required 设置是否必须传递参数,默认值为true;如果设置了默认值,值自动改为false */
System.out.println(pageNum);
System.out.println(pageSize);
return "success";
}
}
@RequestHeader
获取请求头的数据。
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*演示@RequestHeader注解的使用*/
@RequestMapping("/requestHeader")
public String requestHeader(@RequestHeader("cookie") String cookie){
System.out.println(cookie);
return "success";
}
}
@CookieValue
获取cookie中的数据。
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*演示@CookieValue注解的使用*/
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String jsessionId){
System.out.println(jsessionId);
return "success";
}
}
3.9 获取Servlet相关API
SpringMVC支持使用原始ServletAPI对象作为控制器方法的参数进行注入,常用的对象如下:
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
/*原始ServletAPI参数的获取*/
@RequestMapping("/servletAPI")
public String servletAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}
}
四 SpringMVC的响应
4.1 SpringMVC响应方式介绍
页面跳转
-
返回字符串逻辑视图
-
void原始ServletAPI
-
ModelAndView
返回数据
-
直接返回字符串数据
-
将对象或集合转为json返回(任务二演示)
4.2 返回字符串逻辑视图
直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转到指定页面
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
public class UserController {
@RequestMapping(path = "/quick", method = RequestMethod.GET, params={"accountName","money!=100"})
public String quick(){
/*业务逻辑*/
System.out.println("SpringMVC入门成功。。。");
return "success";//在spring-mvc.xml文件中配置了视图解析器之后只需要写逻辑视图名,在真正解析时会拼接为具体的物理文件地址
}
}
4.3 void原始ServletAPI
我们可以通过request、response对象实现响应
/*通过原始servletAPI进行页面跳转*/
@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.通过response直接响应数据
/*response.setContentType("text/html;charset=utf-8");
response.getWriter().write("拉勾网");*/
//借助request对象完成请求转发
//请求转发只有一次请求,请求路径不会发生改变
// request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//借助response对象完成重定向
//重定向相当于发起了两次请求,请求路径会发生改变
// response.sendRedirect(request.getContextPath() + "/webapp/WEB-INF/pages/success.jsp");//不可访问
//WEB-INF目录是一个安全目录,不允许外部请求直接访问该目录资源,只可以进行服务器内部转发
//所以选择直接重定向到index.jsp页面
response.sendRedirect(request.getContextPath() + "/index.jsp");
}
4.4 转发和重定向
企业开发我们一般使用返回字符串逻辑视图实现页面的跳转,这种方式其实就是请求转发。
我们也可以写成:
forward转发
如果用了forward:则路径必须写成实际视图url,不能写逻辑视图。它相当于:
request.getRequestDispatcher("url").forward(request,response)
使用请求转发,既可以转发到jsp,也可以转发到其他的控制器方法。
/*演示forward关键字进行请求转发*/
@RequestMapping("/forward")
public String forward(Model model){
//在model模型中设置一些值
model.addAttribute("username", "haha");
//使用forward关键字请求转发,可以将请求转发到其他的jsp页面,也可以将请求转发到其他的Controller控制器中的方法
//return "forward:/product/findAll";//将请求转发到其他的控制器方法
return "forward:/WEB-INF/pages/success.jsp";//转发到其他jsp页面
}
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>springMVC入门初体验</title>
</head>
<body>
<h3>访问成功。。。</h3>
<!--在success.jsp页面获取在controller类中的方法设置的model值-->
获取的模型中的值为:${username}
</body>
</html>
Redirect重定向
我们可以不写虚拟目录,springMVC框架会自动拼接,并且将Model中的数据拼接到url地址上
/*演示redirect关键字进行重定向*/
@RequestMapping("/redirect")
public String redirect(Model model){
//在model模型中设置一些值
//实际上底层使用的还是request.setAttribute("username", "hanhan"),request的域范围是:一次请求
//而重定向实际上是两次请求,超出了request域范围所以不能获取到model的值
model.addAttribute("username", "hanhan");//在index.jsp页面使用${}不能获取model中的值
return "redirect:/index.jsp";//重定向到其他jsp页面
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1>首页</h1>
获取到重定向中设置的model值:${username}
<%--重定向不能获取到model中的值--%>
</body>
</html>
4.5 ModelAndView
4.5.1 方式一
在Controller中方法创建并返回ModelAndView对象,并且设置视图名称
controller类
/*modelAndView进行页面跳转,方式一*/
@RequestMapping("/returnModelAndView1")
public ModelAndView returnModelAndView1(){
/* Model:模型 作用封装数据 View:视图 作用展示数据 */
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
modelAndView.addObject("name","modelAndView进行页面跳转,方式一");
//设置视图名称 由视图解析器来解析
modelAndView.setViewName("success");//要跳转的视图名称 逻辑视图名
return modelAndView;
}
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>springMVC入门初体验</title>
</head>
<body>
<h3>访问成功。。。</h3>
获取通过modelAndView设置的值:${name}
</body>
</html>
4.5.2 方式二
在Controller中方法形参上直接声明ModelAndView,无需在方法中自己创建,在方法中直接使用该对象设置视图,同样可以跳转页面
controller类
/*modelAndView进行页面跳转,方式二*/
@RequestMapping("/returnModelAndView2")
public ModelAndView returnModelAndView2(ModelAndView modelAndView){
/* Model:模型 作用封装数据 View:视图 作用展示数据 */
//设置模型数据
modelAndView.addObject("name","modelAndView进行页面跳转,方式二");
//设置视图名称 由视图解析器来解析
modelAndView.setViewName("success");//要跳转的视图名称 逻辑视图名
return modelAndView;
}
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>springMVC入门初体验</title>
</head>
<body>
<h3>访问成功。。。</h3>
获取通过modelAndView设置的值:${name}
</body>
</html>
4.6 @SessionAttributes
如果在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在session中存放的数据范围,Spring MVC将存放在model中对应的数据暂存到 HttpSession 中。
注意:@SessionAttributes只能定义在类上
controller类
@Controller
@RequestMapping("/user")//@RequestMapping注解使用在类上就是一级访问目录
@SessionAttributes("username")//表示向request域中(也就是model中)存入key为username的值时,会同步存入session域中
public class UserController {
/*演示forward关键字进行请求转发*/
@RequestMapping("/forward")
public String forward(Model model){
//在model模型中设置一些值
model.addAttribute("username", "haha");
//使用forward关键字请求转发,可以将请求转发到其他的jsp页面,也可以将请求转发到其他的Controller控制器中的方法
//return "forward:/product/findAll";//将请求转发到其他的控制器方法
return "forward:/WEB-INF/pages/success.jsp";//转发到其他jsp页面
}
/*
没有在Controller类上使用@SessionAttributes注解时,当上述方法向model中存了值,在下述方法中返回的success.jsp页面是不能获取到的,当使用了@SessionAttributes注解之后,则可以获取到
*/
/*演示@SessionAttributes的效果,即多个请求之阿健共享数据*/
@RequestMapping("/returnString")
public String returnString(){
return "success";
}
}
4.7 知识小结
-
页面跳转采用返回字符串逻辑视图
- 1.forward转发
- 可以通过Model向request域中设置数据
- 2.redirect重定向
- 直接写资源路径即可,虚拟目录springMVC框架自动完成拼接
- 1.forward转发
-
数据存储到request域中
- 使用Model model 作为参数
- model.addAttribute(“username”, “子慕”);
- 使用Model model 作为参数
五 静态资源访问的开启
当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是 /(缺省),代表对所有的静态资源都进行处理操作,这样就不会执行Tomcat内置的DefaultServlet处理,我们可以通过以下两种方式指定放行静态资源:
方式一:在spring-mvc.xml核心配置文件中进行如下配置
<!--开启静态资源的访问方式1:放行指定的映射路径-->
<!--mapping:放行资源的映射路径 location:静态资源所在的目录 -->
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
<mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
<mvc:resources mapping="/img/**" location="/img/"></mvc:resources>
方式二:在spring-mvc.xml核心配置文件中进行如下配置
<!--开启静态资源的访问方式2:在springmvc配置文件中开启DefaultServlet处理静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler><!--开启的是全局的静态资源-->
/*
没有在Controller类上使用@SessionAttributes注解时,当上述方法向model中存了值,在下述方法中返回的success.jsp页面是不能获取到的,当使用了@SessionAttributes注解之后,则可以获取到
*/
/*演示@SessionAttributes的效果,即多个请求之阿健共享数据*/
@RequestMapping("/returnString")
public String returnString(){
return "success";
}
}
## **4.7** **知识小结**
* 页面跳转采用返回字符串逻辑视图
* 1.forward转发
* 可以通过Model向request域中设置数据
* 2.redirect重定向
* 直接写资源路径即可,虚拟目录springMVC框架自动完成拼接
* 数据存储到request域中
* 使用Model model 作为参数
* model.addAttribute("username", "子慕");
# **五 静态资源访问的开启**
当有静态资源需要加载时,比如jquery文件,通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是 /(缺省),代表对所有的静态资源都进行处理操作,这样就不会执行Tomcat内置的DefaultServlet处理,我们可以通过以下两种方式指定放行静态资源:
**方式一:在spring-mvc.xml核心配置文件中进行如下配置**
```xml
<!--开启静态资源的访问方式1:放行指定的映射路径-->
<!--mapping:放行资源的映射路径 location:静态资源所在的目录 -->
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
<mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
<mvc:resources mapping="/img/**" location="/img/"></mvc:resources>
方式二:在spring-mvc.xml核心配置文件中进行如下配置
<!--开启静态资源的访问方式2:在springmvc配置文件中开启DefaultServlet处理静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler><!--开启的是全局的静态资源-->