1 Spring MVC的入门案例
1.1 前期准备
- 下载开发包:https://spring.io/projects
其实spring mvc的jar包就在之前我们的spring框架开发包中。 - 创建一个java web工程:
- 创建一个jsp用于发送请求:
- jsp中的内容:
<a href="${pageContext.request.contextPath}/hello">Spring MVC入门案例</a> <br/> <a href="hello">Spring MVC入门案例</a>
1.2 拷贝jar包
spring mvc的jar包就在:
除了上面两个jar包之外,还需要拷贝spring的注解ioc所需jar包(包括一个aop的jar包):
1.3 配置核心控制器——一个Servlet
<?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">
<!-- 配置spring mvc的核心控制器 -->
<servlet>
<servlet-name>Spring MVCDispatcherServlet</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<!-- 配置初始化参数,用于读取Spring MVC的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:Spring MVC.xml</param-value>
</init-param>
<!-- 配置servlet的对象的创建时间点:应用加载时创建。
取值只能是非0正整数,表示启动顺序 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVCDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.4 创建spring mvc的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 配置创建spring容器要扫描的包 -->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
1.5 编写控制器并使用注解配置
/**
* spring mvc的入门案例
*/
@Controller("helloController")
public class HelloController {
@RequestMapping("/hello")
public String sayHello() {
System.out.println("HelloController的sayHello 方法执行了。。。。");
return "success";
}
}
1.6 测试
2 入门案例的执行过程及原理分析
2.1 案例的执行过程
- 服务器启动,应用被加载。读取到web.xml中的配置创建spring容器并且初始化容器中的对象。
从入门案例中可以看到的是:HelloController和InternalResourceViewResolver,但是远不止这些; - 浏览器发送请求,被DispatherServlet捕获,该Servlet并不处理请求,而是把请求转发出去。转发的路径是根据请求URL,匹配@RequestMapping中的内容;
- 匹配到了后,执行对应方法。该方法有一个返回值;
- 根据方法的返回值,借助InternalResourceViewResolver找到对应的结果视图;
- 渲染结果视图,响应浏览器。
2.2 Spring MVC的请求响应流程
3 入门案例中涉及的组件
3.1 DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
3.2 HandlerMapping:处理器映射器
HandlerMapping负责根据用户请求找到Handler即处理器,Spring MVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
3.3 Handler:处理器
它就是我们开发中要编写的具体业务控制器。由DispatcherServlet把用户请求转发到Handler。由Handler对具体的用户请求进行处理。
3.4 HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
3.5 View Resolver:视图解析器
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
3.6 View:视图
Spring MVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。
3.7 <mvc:annotation-driven>说明
在Spring MVC的各个组件中,处理器映射器、处理器适配器、视图解析器称为Spring MVC的三大组件。
使用<mvc:annotation-driven>自动加载RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter(处理适配器),可用在Spring MVC.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置,就相当于在xml中配置了:
<!-- Begin -->
<!-- HandlerMapping -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- HandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- HadnlerExceptionResolvers -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver"></bean>
<bean class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver"></bean>
<!-- End -->
注意:一般开发中,我们都需要写上此标签(虽然从入门案例中看,我们不写也行,随着课程的深入,该标签还有具体的使用场景);
明确:我们只需要编写处理具体业务的控制器以及视图。
4 RequestMapping注解
4.1 使用说明
-
源码:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public @interface RequestMapping { }
-
作用:用于建立请求URL和处理请求方法之间的对应关系。
-
出现位置:
- 类上:请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以
/
开头。它出现的目的是为了使我们的URL可以按照模块化管理,例如:
账户模块:
/account/add
/account/update
/account/delete
···
订单模块:
/order/add
/order/update
/order/delete
红色的部分就是把RequsetMappding写在类上,使我们的URL更加精细。 - 方法上:请求URL的第二级访问目录。
- 类上:请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以
-
属性:
value
:用于指定请求的URL,它和path属性的作用是一样的;method
:用于指定请求的方式;params
:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样,例如:params = {"accountName"}
:表示请求参数必须有accountName;-
params = {"moeny!100"}
:表示请求参数中money不能是100。
headers
:用于指定限制请求消息头的条件。
注意:当以上四个属性出现2个或以上时,他们的关系是与的关系。
4.2 使用示例
4.2.1 出现位置的示例
-
控制器代码:
/** * RequestMapping注解出现的位置 */ @Controller("accountController") @RequestMapping("/account") public class AccountController { @RequestMapping("/findAccount") public String findAccount() { System.out.println("查询了账户。。。。"); return "success"; } }
-
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>requestmapping的使用</title> </head> <body> <!-- 第一种访问方式 --> <a href="${pageContext.request.contextPath}/account/findAccount"> 查询账户 </a> <br/> <!-- 第二种访问方式 --> <a href="account/findAccount">查询账户</a> </body> </html>
注意:当我们使用此种方式配置时,在jsp中第二种写法时,不要在访问URL前面加
/
,否则无法找到资源。
4.2.2 method属性的示例
-
控制器代码:
/** * 保存账户 * @return */ @RequestMapping(value="/saveAccount",method=RequestMethod.POST) public String saveAccount() { System.out.println("保存了账户"); return "success"; }
-
jsp代码:
<!-- 请求方式的示例 --> <a href="account/saveAccount">保存账户,get请求</a> <br/> <form action="account/saveAccount" method="post"> <input type="submit" value="保存账户,post请求"> </form>
注意:当使用get请求时,提示错误信息是405,信息是“方法不支持get方式请求”:
4.2.3 params属性的示例
-
控制器代码:
/** * 删除账户 * @return */ @RequestMapping(value="/removeAccount",params= {"accountName","money>100"}) public String removeAccount() { System.out.println("删除了账户"); return "success"; }
-
jsp中的代码:
<!-- 请求参数的示例 --> <a href="account/removeAccount?accountName=aaa&money>100">删除账户,金额100</a> <br/> <a href="account/removeAccount?accountName=aaa&money>150">删除账户,金额150</a>
注意:当我们点击第一个超链接时,可以访问成功。
当我们点击第二个超链接时,无法访问。如下图: