Spring MVC配置介绍

一、Spring MVC 纵览

Spring MVC就是Spring框架对MVC设计模式的实现,通过Spring MVC ,我们可以快速的构建灵活、松耦合的web服务。再具体介绍Spring MVC 之前,我们先看一下它的请求处理过程:

1.1 springMVC 的请求过程

1. 请求会首先发送到DispatchServlet,这是spring的前置Servlet,它会接收请求并转发给spring的MVC controller,也就是业务controller
2. DispatchServlet通过HandlerMapping确定将请求转发给哪个controller,HandlerMapping主要通过请求中的URL确定映射关系的
3. DispatchServlet将请求转发给确定的controller之后,controller负责处理这个请求,一般会通过调用service层进行业务逻辑处理
4. 当controller处理完请求后,它会把业务处理结果封装成model,为了使处理结果的model在页面上更好的展示,controller还会指定展示model对应的view(比如一个JSP页面),当controller确定了model和view之后,会把它们以请求的形式再转发给DispatchServlet
5. DispatchServlet通过查询ViewResolver找到view对应的页面
6. DispatchServlet最终把model交给页面进行渲染
7. 页面对model进行渲染,将结果展示到客户端,整个请求结束

1.2 配置Spring MVC

其实Spring MVC的核心就是DispatchServlet,配置Spring MVC的过程就是配置DispatchServlet的过程。

1.2.1 配置DispatchServlet

Spring的配置有两种方式,一种通过web.xml配置,另一种就是通过Java配置,在这里我们主要讲如何在web.xml中配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
    <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class>
</listener>
<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

主要配置项:

  1. <context-param><listener>:配置Spring的RootContext,对应配置文件为root-context.xml
  2. <servlet><servlet-mapping>:配置Spring的WebContext,对应配置文件默认为为WEB-INF/{servlet-name}-servlet.xml

可能有些人还不太清楚为什么要这样配置,在具体讲解之前,先介绍Spring MVC中的两个context(上下文)。

理解两个context

我们知道,Spring有一个核心容器也就是ApplicationContext,所有的Spring组件都由这个ApplicationContext进行管理。但是在Web项目中,Spring会维护两个context:

1. WebContext

第一个Context就是由DispatchServlet创建的WebContext,负责装载web组件相关的bean,比如controllers、view resolvers、handler mapping等,对应的配置文件是WEB-INF/{servlet-name}-servlet.xml,在上面例子中我们配置的Servlet的名字是spring,所以它默认加载spring-servlet.xml配置文件作为上下文。

但是我们也可以自己指定一个WebContext配置文件位置,比如指定/WEB-INF/spring/appServlet/servlet-context.xml路径下的配置文件:

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/appServlet/servlet-context.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

2. RootContext

RootContext是由ContextListener加载的,它主要装载除web组件之外的应用程序组件,比如jdbc、mybatis等组件。<context-param>标签指定了RootContext配置文件的位置,并由<listener>标签指定的Listener类进行装载。

1.2.2 启用Spring MVC

上面的配置其实已经基本ok了,但是一个完整的Spring MVC应用还需要controller、service、view等web组件,所以我们还要在配置中启用注解及自动包扫描等功能,方便web组件的自动发现,这些应该在上面介绍的WebContext对应的配置文件中进行配置,也就是在spring-servlet.xml中配置:

<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-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <mvc:annotation-driven/>
    <context:component-scan base-package="com.springmvc.demo" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

主要配置项:

  1. <mvc:annotation-driven/>标签作用是开启注解
  2. <context:component-scan/>标签目的是启用自动包扫描,这样spring框架就会自动扫描被注解的类,纳入到WebContext中。

通过上面的配置,Spring MVC的主要配置就已经完成了,我们现在就可以编写Spring MVC的组件了,我们先从controller开始。

二、写一个controller

 2.1 写一个简单的controller

@Controller
public class HomeController {
@RequestMapping(value="/", method= RequestMethod.GET)
    public String home() {
        return "home";
    }
}

声明controller组件:写一个controller很简单,@controller注解声明当前类是一个controller类,上面配置中我们开启了ComponentScan,被@controller注解的类会被自动装载到spring application context中。当然我们使用@component组件效果也是一样的,只不过@controller更能体现controller角色。

定义请求路径: HomeController类里面只有一个home()方法,并且还携带一个@RequestMapping注解,注解中的value属性定义了这个方法的访问路径是“/”,method属性定义了这个方法只处理get请求。

定义渲染view:我们可以看到,home()方法很简单,仅返回了一个“home”字符串。默认情况下,方法返回的字符串默认会被解析成view的名称,DispatcherServlet 会让ViewResolver解析这个view名称对应的真是view页面。我们上面已经配置了一个InternalResourceViewResolver,返回的home会被解析/WEB-INF/views/home.jsp。

写完controller之后我们可以通过测试类测试一下,写一个测试controller:

public class HomeControllerTest {
    @Test
    public void testHomePage() throws Exception {
        HomeController controller = new HomeController();
        Assert.assertEquals("home", controller.home());

    }
    @Test
    public void testHomePageMVC() throws Exception {
        HomeController controller = new HomeController();
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
        mockMvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.view().name("home"));
    }

}

2.2 定义一个类层次的路径映射

其实@RequestMapping注解既可以注解方法又可以注解类,当注解类时,访问类中所有的方法就必须加上类路径。另外@RequestMapping中的值可以是一个路径数组,当传入一个数组时,我们可以通过数组中的任何一个路径访问到这个类.

@Controller
@RequestMapping({"/", "/homepage"})
public class HomeController {
    ...
}

2.3 返回Model数据给view层

我们知道通常情况下,controller处理完业务后会返回结果数据给view层。为此,SpringMVC提供了Model类来封装结果数据,封装的过程是自动的,我们只需要在方法中加入Model参数即可:

public String getUsers(Model model) {
    model.addAttribute( userService.findSpittles( Long.MAX_VALUE, 20));
    return "userView";
}

Model其实就是一个Map,view层会自动解析model中的数据,然后渲染结果给client端。上面的model.addAttribute方法没有指定key,key值会被默认设置为对象的类型名,比如上例子中对象类型是List<User>,则key值默认为:userList。方法最后返回的String值userView会直接作为view的名称。

当然我们也可以明确指定返回数据模型的key值:

public String getUsers(Model model) {
    model.addAttribute("userList", userService.findUsers( Long.MAX_VALUE, 20));
    return "userView";
}

如果我们不想使用Spring的Model类,我们也可以用java.util.Map类替换Model,这两个效果是完全一样的:

public String getUsers(Map map) {
    map.addAttribute("userList", userService.findUsers( Long.MAX_VALUE, 20));
    return "userView";
}

除了上面两种方式之外,我们还可以这么写:

@RequestMapping(method=RequestMethod.GET)
public List<User> getUsers() {
    return userService.findUsers(Long.MAX_VALUE, 20));
}

这种方式比较特殊,我们既没有设置返回的Model,又没有指定渲染Model的view,仅仅返回处理的结果对象。遇到这种情况时,Spring MVC会把返回的对象会自动放入Model中,其key就是对象的类型名,即userList。而对应的view名称则默认与请求路径名一致,例如我们的请求路径是这样:

@Controller
@RequestMapping("/users")
public class UserController {
    ... ...
}

那么对应渲染结果的view就是users

三、 处理请求数据

SpringMVC提供了多种数据传输方式:

  • QueryParameter:查询参数
  • Form Parameters:表单参数
  • Path variables:路径变量

下面我们逐一说明。

3.1 获取查询参数

首先什么是查询参数呢?比如我们有一个这样的请求http://localhost:8080/user/queryUsers?pageNo=1&count=5,在这个请求中,参数值都是通过URL中?后面的参数传递过来的,这种方式就是查询参数传值。如果要解析查询参数中的值,我们需要用到@RequestParam注解,它会将请求参数映射到方法参数:

@RequestMapping(value = "/getUsersByPage", method = RequestMethod.GET)
public String getUsersByPage(@RequestParam(value = "pageNo",defaultValue = "1") long pageNo,@RequestParam(value = "count",defaultValue = "5") long count ,Model model) {
    model.addAttribute(userService.getAllUsers());
    return "userListPageView";
}

需要注意的是,我们在配置请求参数时可以指定参数的默认值,当client端传过来的参数值不存在或者为空时,就会采用这个默认值,还有一点,因为查询参数都是String类型,所以这里的默认值也都是String类型。

除了通过查询参数传递参数值之外,还有一种流行的方式就是通过请求路径传递参数值,特别是在讨论构建基于资源的服务时会经常用到这种方式。(注:基于资源的服务可以简单看做所有请求都是针对资源,所有的返回结果也是资源)

3.2 通过请求路经获取参数

比如我们有一个根据用户id查询用户信息的需求,通过上面介绍的方式我们可以这么做:

@RequestMapping(value = "/queryUser", method = RequestMethod.GET)
public String queryUser(@RequestParam(value = "employeeId") long employeeId,Model model){
    model.addAttribute(manager.queryEmployeeVO(employeeId));
    return "employee";
}

那么我们客户的的请求路径应该是这样:/employee/queryEmployee ?employeeId=12345,尽管也可以满足需求,但这样不太符合基于资源的理念。理想的情况是,资源应该是由请求路径决定的,而不是由请求参数决定。或者说,请求参数不应该被用来描述一个资源。/employee/12345 这种请求方式显然比/employee/queryEmployee ?employeeId=12345更能合适,前者定义了要查询的资源,而后者更强调了通过参数进行操作。

为了达到构建基于资源的controller这个目标,Spring MVC允许请求路径中包含一个占位符,占位符名称需要用一对{}括起来。在客户的请求资源时,请求路径的其它部分还是用来匹配资源路径,而占位符部分则直接用来传输参数值。下面就是通过占位符的方式实现路径中传递参数值:

@RequestMapping(value ="/{userId}", method = RequestMethod.GET)
public String queryUser(@PathVariable(value = "userId") long userId, Model model){
    model.addAttribute(userService.queryUser(employeeId));
    return "userView";
}

上面例子可以看到,方法参数中有一个@PathVariable的注解,这个注解的意思就是不管请求路径中占位符处的值是什么,它都会被传递到@PathVariable注解的变量中。比如按照上面的配置,如果我们的请求是/employee/12345,则123456便会传入变成userId的值。需要注意的是,如果方法参数值和占位符名称一样,我们也可以省略@PathVariable中的属性值:

@RequestMapping(value ="/{userId}", method = RequestMethod.GET)
public String queryUser(@PathVariable long userId, Model model){
    model.addAttribute(userService.queryUser(employeeId));
    return "userView";
}

在请求的数据量很小的时候使用查询参数和路径参数还是可行的,但是有时候我们请求的数据量会很大,再用上面两种方式就显得有点不太合适,这时就需要考虑用第三种方式:表单参数。

四、处理表单数据

一个Web应用不单单只是给用户展示数据,很多时候它还需要与用户交互获取用户数据,表单就是获取用户数据最常见的方式。

比如我们有个注册表单:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
    <head>
        <title>Spittr</title>
        <link rel="stylesheet" type="text/css"  >
    </head>
    <body>
        <h1>Register</h1>
        <form method="POST">
            First Name: <input type="text" name="name" /><br/>
            Last Name: <input type="text" name="accountNo" /><br/>
            Password: <input type="password" name="password" /><br/>
            <input type="submit" value="Register" />
        </form>
    </body>
</html>

4.1 写一个接收表单数据的controller

表单都是以post方式提交的,所以我们的controller接受的应该是个post请求:

@Controller
@RequestMapping("/user")
public class RegisterController {
    @Autowired
    private RegisterService registerService;
    @RequestMapping(value="/register", method=RequestMethod.POST)
    public String processRegistration(User user) {
        registerService.register(user);
        return "redirect:/user/" + user.getName();
    }
}

在上面例子中,出了接收的请求是post之外,注册方法还有一个含有User对象的参数,这个User对象中含有name、password、accountNo属性,SpringMVC会根据名称从请求中解析相同名称参数并赋值到对象属性中。

当注册方法保存用户信息之后,会返回一个字符串redirect:/user/,这个字符串与前面讲到的都不同,它返回的并不是一个view的名称,而是一个redirect重定向请求。因为返回的字符串中含有一个redirect:重定向关键字,当InternalResourceViewResolver类遇到这个关键字时,它将会拦截这个字符串并把它解析成一个重定向请求而不是view名称。

InternalResourceViewResolver除了能够识别redirect:关键字之外,它还能识别forward:关键字,并把包含forward:关键字的字符串解析成forward请求。

4.2 验证表单

在Spring3.0以后,SpringMVC便支持Java Validation API了,Java Validation API提供了一些注解来约束对象属性值,这些注解有:

注解 解释
@AssertFalse The annotated element must be a Boolean type and be false.
@AssertTrue The annotated element must be a Boolean type and be true.
@DecimalMax The annotated element must be a number whose value is less than or equal toa given BigDecimalString value.
@DecimalMin The annotated element must be a number whose value is greater than orequal to a given BigDecimalString value.
@Digits The annotated element must be a number whose value has a specified number of digits.
@Future The value of the annotated element must be a date in the future.
@Max The annotated element must be a number whose value is less than or equal to a given value.
@Min The annotated element must be a number whose value is greater than or equal to a given value.
@NotNull The value of the annotated element must not be null.
@Null The value of the annotated element must be null.
@Past The value of the annotated element must be a date in the past.
@Pattern The value of the annotated element must match a given regular expression.
@Size The value of the annotated element must be either a String, a collection, or an array whose length fits within the given range.

我们可以利用这些注解给User对象添加一些验证,比如非空和字符串长度验证:

public class User {
    @NotNull
    @Size(min=3,max=20)
    private String name;
    @NotNull
    @Size(min=6,max=20)
    private String password;
    @NotNull
    @Size(min=3,max=20)
    private String accountNo;

}

我们还需要通过@Valid标签在方法中对User启用参数验证:

@RequestMapping(value="/register", method=RequestMethod.POST)
public String processRegistration(@Valid User user, Errors errors) {
    if(errors.hasErrors()){
        return "register";
    }
    registerService.register(user);
    return "redirect:/user/" + user.getName();
}

在上面例子中,我们在方法中的User参数前面添加了@valid注解,这个注解会告诉Spring框架需要启用对这个对象的验证。如果发现任何验证错误,错误信息都将会被封装到Errors对象中,我们可以通过errors.hasErrors()方法判断是否验证通过。

Spring MVC其它相关文章:

时间: 2024-08-01 08:58:12

Spring MVC配置介绍的相关文章

spring mvc配置

第一. 引入jar包 第二. web.xml 文件修改 <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置Spring MVC 下的配置文件的位置和名称 --> <init-par

Spring MVC配置太多?试试Spring Boot

SpringMVC相信大家已经不再陌生了,大家可能对于Spring的各种XML配置已经产生了厌恶的感觉,Spring官方发布的Springboot 已经很长时间了,Springboot是一款"约定优于配置"的轻量级框架:Springboot首先解决的就是各种繁琐的XML配置,你可以不用任何XML配置,进行web服务的搭建,其次是Springboot本身就继承了web服务器,如果说前端开发人员想在本地启动后端服务不需要进行各种配置,几乎可以做到一键启动. 再有就是目前大热的微服务,而Sp

Spring MVC 页面渲染( render view )

一.理解view解析过程 1.1 从逻辑view到物理view 在Spring MVC 中,controllers不会负责具体的页面渲染,它仅仅是调用业务逻辑并返回model数据给view层,至于view层具体怎么用HTML展现,由专门的view层具体负责,这就是MVC模式,业务层与展示层是松耦合的.那么,Spring MVC是如何解耦合请求处理逻辑和页面渲染的呢? 我们在Spring MVC配置介绍文章中已经知道,controller在处理外业务逻辑之后会返回一个逻辑view的字符串,那么Sp

Spring MVC框架的高级配置

高级 本文将为您提供关于Spring MVC框架的配置技巧,以帮助管理基于Spring的web应用程序的多个实例.本配置管理主题常被学术界所忽略,但是,这对于现实的web开发尤为重要.本主题并不直接关联任何具体的技术,因此,我们将从最基本的概念开始对这个问题进行说明.下面,我们将根据Spring MVC框架,为基于本技术开发的项目提供一系列的解决方案. Spring配置 人们经常会在一台以上的主机上配置一种Web应用程序.例如,在生产中,一个网站可能只有一个实例.除了此实例外,开发人员可以在用于

Spring MVC完全注解方式配置web项目_java

在servlet 3.0 开始web项目可以完全不需要web.xml配置文件了,所以本文的配置只在支持servlet 3.0及以上的web容器中有效 使用的是spring mvc (4.3.2.RELEASE) + thymeleaf(3.0.2.RELEASE), 持久层使用的 spring的 JdbcTemplate, PS:推荐一个很好用的对JdbcTemplate封装的框架:https://github.com/selfly/dexcoder-assistant  . 下面开始具体的配置

Spring MVC 框架搭建配置方法及详解_JSP编程

现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.comm

使用Spring 2.5基于注解驱动的Spring MVC

概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 XML 配置文件中定义请求和 Controller 的映射关系,仅仅使用注解就可以让一个 POJO 具有 Controller 的绝大部分功能 -- Spring MVC 框架的易用性得到了进一步的增强.在框架灵活性.易用性和扩展性上,Spring MVC 已经全面超越了其它的 MVC 框架,伴随

Spring MVC前后端中文编码解码问题

简单介绍一下,前端通过jQuery的ajax.post()方法来发送请求,默认编码类型为utf-8,调用方法如下:   服务端使用Spring MVC进行处理,上面的脚本POST的参数中,有一部分是包含中文字符的,所以,需要Spring MVC配置一下默认的编码格式,需要在web.xml中配置如下的内容,来设定默认编码格式:   配置后,在相应的Controller中就可以直接获取传递的中文参数内容,而不需要进行任何的解码操作,如下:              顺便说一句,这里面使用了Sprin

Eclipse使用maven搭建spring mvc图文教程_java

本文为大家介绍了Eclipse使用maven搭建spring mvc的详细步骤,供大家参考,具体内容如下 1. 环境配置 a). Java 1.7 b). Eclipse luna c). Maven3.2.5 d). Spring 4.1.4 2. 创建maven工程 a). 打开eclipse,file->new->project->Maven->Maven Project b). 下一步 c). 选择创建的工程为webapp,下一步 d). 填写项目的group id和art