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>

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

1.2.2 理解两个context

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

1. WebContext

第一个Context就是由DispatchServlet创建的WebContext,负责装载web组件相关的bean,比如controllers、view resolvers、handler mapping等,对应的配置文件是{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.3 启用Spring MVC

上面的配置其实已经基本ok了,但是一个完整的Spring MVC应用还需要controller、service、view等组件,这些后面会详细讲,现在我们先在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>

<mvc:annotation-driven/>标签作用是开启注解

<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()方法判断是否验证通过。

未完待续……

时间: 2024-10-04 22:08:25

Spring MVC配置介绍的相关文章

spring mvc配置 + dbcp数据源+jdbcTemplate

spring mvc配置 + dbcp数据源+jdbcTemplate 最近打算仔细研究一下spring,就从用了2年的spring mvc开始吧,初学者可以看看,大神就pass好了,呵呵.... 首先去spring官网下载完整的spring包,包含libs, docs和schema,spring的版本是3.2.4 我们来看一下spring的lib包都有那些内容: 上面图片中除红色框内的两个jar其它都是spring官方提供的jar包,红色框内的jar我们在配置事务的时候会用到,我们一会再说.我

Spring Boot 实践折腾记(五):自定义配置,扩展Spring MVC配置并使用fastjson

每日金句 专注和简单一直是我的秘诀之一.简单可能比复杂更难做到:你必须努力理清思路,从而使其变得简单.但最终这是值得的,因为一旦你做到了,便可以创造奇迹.--源自乔布斯 题记 前两天有点忙,没有连续更新,今天接着聊.金句里老乔的话说得多好,但能真正做到的人又有多少?至少就我个人而言,我还远远没有做到这样,只是一个在朝着这个方向努力的人,力求简明易懂,用大白话让人快速的明白理解,简单的例子上手,让使用的人更多的去实战使用扩展,折腾记即是对自己学习使用很好的一次总结,对看的人也是一个参考的方法,希望

spring mvc简单介绍xml版

spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServlet:负责接受所有的请求,就像普通的servlet一样,此接口只是简单的负责处理接受请求. 2.HandlerMapping:当接受到请求后,由此组件负责解析请求,知道该请求要访问那个具体的Controller(具体的Servlet). 3.HandlerAdaper:负责调用具体的Controll

最小可用 Spring MVC 配置

[最小可用 Spring MVC 配置] 1.导入有概率用到的JAR包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/mave

spring MVC配置详解[转]

现在主流的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

Spring3.X 配置----Spring MVC 配置

导论: 什么是Spring MVC? Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架.通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如  JavaServer Pages(JSP)技术.Velocity.

spring MVC配置详解(转)

现在主流的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 MVC配置

spring mvc的配置 添加spring的支持,导入spring需要的jar包. 配置web.xml. 1 <!--IOC容器配置 --> 2 <context-param> 3 <param-name>contextConfigLocation</param-name> 4 <param-value>/WEB-INF/spring/spring.xml 5 /WEB-INF/spring/spring-*.xml 6 </param-

spring MVC配置详解

现在主流的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