从一个Hello World入门Spring MVC
Spring MVC是Spring 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一。Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
Spring MVC采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。同时,Spring MVC也支持 REST 风格的 URL 请求。
一、在Maven文件里面添加以下配置来管理jar包
<!-- Spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring mvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
二、在 web.xml 中配置 DispatcherServlet
配置 DispatcherServlet :DispatcherServlet 默认加载 /WEBINF/< servletName-servlet >.xml
的 Spring 配置文件,启动 WEB 层的 Spring 容器。可以通过 contextConfigLocation 初始化参数自定
义配置文件的位置和名称。
<?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>Archetype Created Web Application</display-name>
<!--web容器启动和关闭的监听器,只负责web容器启动和关闭的事件-->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!--1、Spring配置 -->
<!--启动spring容器 ContextLoaderListener 将web容器和spring容器整合-->
<!-- Bootstraps the root web application context before servlet initialization -->
<!--在servlet初始化之前引导根web应用程序上下文-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</context-param>
<!-- 2、SpringMVC配置 -->
<!-- SpringMVC的前端控制器,拦截所有请求 -->
<!-- 配置 DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置 DispatcherServlet 的一个初始化参数: 配置 SpringMVC 配置文件的位置和名称 -->
<!--
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
-->
<!--
实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件, 而使用默认的.
默认的配置文件为: /WEB-INF/<servlet-name>-servlet.xml
dispatcherServlet-servlet.xml
-->
<!--<load-on-startup>是dispatcherServlet在当前web应用被加载的时候就创建,
而不是等第一次请求的时候被创建-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 3、字符编码过滤器,一定要放在所有过滤器之前 -->
<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>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 4、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
三、加入 Spring MVC 的配置文件
dispatcherServlet-servlet.xml文件示例代码如下:
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--SpringMVC的配置文件,包含网站跳转逻辑的控制,配置 -->
<!--***********需要修改的**********************-->
<!--**********1、base-package***************-->
<!--**********2、视图解析器的prefix和suffix的value*****-->
<!-- 1、配置自动扫描的包 只扫描Controller-->
<context:component-scan base-package="com.spring.mvc" use-default-filters="false">
<!--只扫描控制器 -->
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 2、配置视图解析器,方便页面返回 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 3、两个标准配置 -->
<!-- 将springmvc不能处理的请求交给tomcat -->
<mvc:default-servlet-handler/>
<!--
default-servlet-handler 将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,
它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求,
就将该请求交由 WEB 应用服务器默认的Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理
一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定
-->
<!-- 在实际开发中通常都需配置 mvc:annotation-driven 标签 -->
<!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax...映射动态请求 -->
<mvc:annotation-driven/>
<!-- 文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/> <!-- 10m -->
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
</beans>
四、编写处理请求的处理器,并标识为处理器
@Controller
@RequestMapping("/mvc")
public class HelloWorld {
@RequestMapping("/hello")
public String HelloWorld(){
return "success";
}
}
五、编写视图 success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<H4>Hello SpringMVC</H4>
</body>
</html>
使用 @RequestMapping 映射请求
Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求。DispatcherServlet 截获请求后,就通过控制器上@RequestMapping 提供的映射信息确定请求所对应的处理方法。在控制器的类定义及方法定义处都可标注@RequestMapping:
– 类定义处:提供初步的请求映射信息。相对于 WEB 应用的根目录。
– 方法处:提供进一步的细分映射信息。相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于WEB 应用的根目录。
@RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头映射请求。 @RequestMapping 的 value、method、params 及 heads分别表示请求 URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。
params 和 headers支持简单的表达式:
param1: 表示请求必须包含名为 param1 的请求参数
!param1: 表示请求不能包含名为 param1 的请求参数
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2的两个请求参数,且 param1 参数的值必须为 value1。
@RequestMapping(value = "hello", method = RequestMethod.POST)
public String HelloWorld(){
helloService.sayHello();
return "success";
}
@PathVariable 映射 URL 绑定的占位符
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx”) 绑定到操作方法的入参中。
@RequestMapping("/hello/{id}")
public String HelloWorld(@PathVariable int id){
helloService.sayHello();
System.out.println("ID:" +id);
return "success";
}
使用 @RequestParam 绑定请求参数值
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法:
– value:参数名。
– required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常。
@RequestMapping("/hello")
public String HelloWorld(@RequestParam(value = "id", required = false) int id){
helloService.sayHello();
System.out.println("ID:" +id);
return "success";
}
使用 @RequestHeader 绑定请求报头的属性值
请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中。
@RequestMapping("/hello")
public String HelloWorld(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive,
@RequestParam(value = "id", required = false) int id){
helloService.sayHello();
System.out.println("ID:" +id);
return "success";
}
使用 @CookieValue 绑定请求中的 Cookie 值
@CookieValue 可让处理方法入参绑定某个 Cookie 值。
@RequestMapping("/hello")
public String HelloWorld(@CookieValue(value = "sessionId", required = false) String sessionId,
@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive,
@RequestParam(value = "id", required = false) int id){
helloService.sayHello();
System.out.println("ID:" +id);
return "success";
}
使用 POJO 对象绑定请求参数值
Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.deptName 等
public class User {
private int userId;
private String userName;
private Dept dept;
public User() {
}
public User(int userId, String userName, Dept dept) {
this.userId = userId;
this.userName = userName;
this.dept = dept;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", dept=" + dept +
'}';
}
}
public class Dept {
private int deptId;
private String deptName;
public Dept() {
}
public Dept(int deptId, String deptName) {
this.deptId = deptId;
this.deptName = deptName;
}
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
@RequestMapping("/hello")
public String HelloWorld(User user){
System.out.println("USER:" + user);
return "success";
}
/hello?userId=100&userName=Jery&dept.deptId=1&dept.deptName=测试部
使用 Servlet API 作为入参
@RequestMapping("/hello")
public String HelloWorld(HttpServletRequest request,
HttpServletResponse response,
HttpSession session,
@RequestParam("userId") int userId){
return "success";
}
MVC 的 Handler 方法可以接受的 ServletAPI 类型的参数如下所示:
• HttpServletRequest
• HttpServletResponse
• HttpSession
• java.security.Principal
• Locale
• InputStream
• OutputStream
• Reader
• Writer
注:需要导入ServletAPI 的jar包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>