Spring框架:SpringMVC详解

SpringMVC的工作流程。最先接触到请求的是DispatcherServlet,它会将请求根据配置文件转发到控制器,控制器返回视图名称和一个Model表示处理结果。DispatcherServlet再将处理结果发送给视图模板引擎,由它进行页面的渲染。下图是整个过程。

基本配置

声明servlet。首先要在web.xml中声明Spring的Servlet,代码如下:

<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>

重要提示:这里的url-pattern不能用/*,会导致所有的请求都返回404错误。因为我们自己编写的控制器只会返回一个视图名称,而解析视图名称的时候还会再次通过servlet获取资源,如果使用/*,那么所有的资源都由Spring框架来处理,但是Spring控制器中没有任何jsp文件,如果设置成/,那么对于xxx.jsp文件就会优先通过Tomcat自带的Servlet返回静态资源。

静态资源。让Spring框架处理所有的静态资源,需要如下的声明。以下是spring-servlet.xml文件,文件名称servlet-name有关。

<beans xmlns="...">
  <mvc:resources mapping="/res/**" location="/res/"/>
</beans>

注解声明。为了开启注解方式的配置,需要在spring-servlet.xml中声明:

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

控制器

控制器的编写非常灵活,下面看几个例子。

// 最简单的例子,只要学会这个就能解决大部分问题了
@Controller
public class TestController {
    // 映射请求URL,返回一个model和视图名称
    @RequestMapping("/test1")
    public String test1(Model model) {
        return "hello";
    }
}

// RequestMapping用法
@Controller
@RequestMapping("/myapp")
public class MyAppController {
    // 通过/myapp访问
    @RequestMapping(method=RequestMethod.GET)
    public Map<String, String> get() {
    }

    // 通过/myapp/xxx访问
    @RequestMapping(value="/{name}", method=RequestMethod.GET)
    public Map<String, String> getForName(@PathVariable("name") String name) {
    }

    @RequestMapping(method=RequestMethod.POST)
    public String add(@Valid AppointmentForm appointment, BindingResult result) {
    }
}

// URL中包含多个变量
@Controller
@RequestMapping("/people/{peopleId}")
public class TestController {
    @RequestMapping("/order/{orderId}"
    public void getOrder(@PathVariable("peopleId") int peopleId, @PathVariable("orderId") String orderId, Model model) {
    }
}

// URL正则匹配
@Controller
@RequestMapping("/people/{peopleId:[0-9]+}")
public class TestController {
}

// 匹配请求中的参数
@Controller
public class Test {
    @RequestMapping(value="/test", params="name=alice")
    public void test() {
    }

    // 没有name参数的请求
    @RequestMapping(value="/test" params="!name") {
    }
}

// 匹配Http请求报头
@Controller
public class Test() {
    @RequestMapping(value="/test", headers="Accept-Encoding=UTF-8")
    public void test() {
    }

    // Header中存在Cookie
    @RequestMapping(value="/test", headers="Cookie")
    public void test() {
    }
}

// 接受json请求
@Controller
public class TestController {
    @RequestMapping(value="/test" method=RequestMethod.POST, consumes="application/json")
    public void test(@RequestBody People people, Model model) {
    }
}

// 返回json结果
@Controller
public class TestController {
    @RequestMapping(value="/test", method=RequestMethod.GET, produces="application/json")
    public @ResponseBody People getPeople() {
    }
}

// Cookie
@RequestMapping("/test")
public void test(@CookieValue("Hello") String hello) {
}

// Http头
@RequestMapping("/test")
public void test(@RequestHeader("Accept-Encoding") String encoding) {
}

// 文件上传
@RequestMapping("/test/")
public void test(@RequestParam(value="image", required=false)MultipartFile image) {
}

// 参数验证
@Controller
public class TestController {
    @Size(min=3, max=20, message="xxx")
    @Pattern(regexp="^[a-zA-Z][a-zA-Z0-9]*")
    private String username;
}

// 错误处理
@Controller
public class TestController {
    @RequestMapping("/test")
    public String test() {
    }

    @ExceptionHandler(IOException.class)
    public ResponseEntity(String) error() {
    }
}

视图

当控制器返回一个视图名称之后,需要通过ViewResolver解析视图。ViewResolver有多种类型:InternalResourceViewResolver、TilesViewResolver、FreemarkerViewResolver、VelocityViewResolver等等。

配置视图引擎。在xxxx-servlet.xml中加入以下代码即可。

<!--简单的JSP模板引擎-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/"/>
  <property name="suffix" value=".jsp"/>
</bean>

<!--JSTL模板引擎-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
  <property name="prefix" value="/WEB-INF/views/"/>
  <property name="suffix" value=".jsp"/>
</bean>

<!--Tiles模板引擎-->
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
  <property name="definitions">
    <list>
      <value>/WEB-INF/views/**/views.xml</value>
    </list>
  </property>
</bean>

如果使用的是InternalResourceViewResolver,那么不需要额外的配置,只要返回文件名就可以了。比如下面的代码会渲染/WEB-INF/views/test.jsp

public String test(){
    return "test";
}

如果需要跳转,只要返回redirect:即可,下面请看例子。

public String test() {
    return "redirect:/hello/test/xxx";
}

拦截器

拦截器需要在xxx-servlet.xml中声明,代码如下:

<mvc:interceptors>
    <!--简单拦截器-->
    <bean class="com.example.LoginInterceptor/>

    <!--限定拦截URL-->
    <mvc:interceptor>
        <mvc:mapping path="/admin/*"/>
        <bean class="com.example.AdminInterceptor/>
    </mvc:interceptor>
</mvc:interceptors>

RESTful集成

REST是一种URL规范,所有的API都不包含QueryString。REST注重资源,而传统的API注重行为。REST通过HTTP Method的不同来做出不同的行为。请看下面几个REST API的例子。返回的结果可以是XML或者JSON。

http://test.com/user/alice
http://test.com/question/1232/answer/321

Spring MVC由于它的映射机制比较良好,因此实现REST API并不困难。下面请看一个例子。

@Controller
public class TestController {
    @RequestMapping("/user/{id}", method=RequestMethod.PUT)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public String updateUser(@PathVariable("id") long id, @Valid User user) {
    }

    @RequestMapping("/user/{id}", method=RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable("id") long id) {
    {
    }

    @RequestMapping("/user/{id}", method=RequestMethod.GET)
    public @ResponseBody User getUser(@PathVariable("id") long id) {
    }

    @RequestMapping("/user", method=RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public @ResponseBody User createUser(@Valid User user, BindingResult result, HttpServletResponse response) throws BindException {
        long userId = service.createUser(user);

        // 返回资源位置
        response.setHeader("Location", "/user/" + userId);

        return user;
    }
}

资源的表述。资源的表述有多种方式,html/xml/json,html适合给人类看,而xml/json适合用于系统之间的通信。定义资源表述可以通过ContentNegotiatingViewResolver。需要在Spring配置中加入如下代码。

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaType">
    <map>
      <entry key="json" value="application/json"/>
      <entry key="xml" value="text/xml"/>
      <entry key="htm" value="text/html"/>
    </map>
  </property>
  <property name="defaultContentType" value="text/html"/>
</bean>

Spring通过多种途径确定该返回哪种格式:URL扩展名,queryString参数,HTTP Header中的Accept字段。

时间: 2024-08-05 23:41:49

Spring框架:SpringMVC详解的相关文章

Spring框架Aop详解

一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址:http://www.cnblogs.com/xrq730/p/4919025.html AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入封装.继承.多态等概念来建立一种对象层次

S2SH框架集成详解(Struts 2.3.16 + Spring 3.2.6 + Hibernate 3.6.10)

近期集成了一次较新版本的s2sh,出现了不少问题,网上资料也是良莠不齐,有的甚至就是扯淡,简单的把jar包扔进去就以为是集成成功了,在这里整理一下详细的步骤,若哪位有什么不同看法,可以留言,欢迎批评改正. 首先说下集成的环境,Eclipse 4.4,Tomcat 7.0.54,Struts2.3.16,Hibernate3.6.10,Spring3.2.6 相关JAR包已上传至百度云:http://pan.baidu.com/s/1pJluA5l 搭建Struts2框架 1. 创建Java We

转载:Spring MVC配置详解

以下内容引自:http://www.cnblogs.com/superjt/p/3309255.html spring MVC配置详解 现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hiber

Spring——jar包详解(转)

Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spring 2.5.6的时候需要asm jar包,spring3.0开始提供它自己独立的asm jar包 org.springframework.aspects——Spring提供的对AspectJ框架的整合 org.springframework.beans——所有应用都用到,包含访问配置文件,创建和

Spring的AOP详解

Spring的AOP详解 一.AOP基础 1.1AOP是什么 考虑这样一个问题:需要对系统中的某些业务做日志记录,比如支付系统中的支付业务需要记录支付相关日志,对于支付系统可能相当复杂,比如可能有自己的支付系统,也可能引入第三方支付平台,面对这样的支付系统该如何解决呢? 传统解决方案 1.日志部分定义公共类LogUtils,定义logPayBegin方法用于记录支付开始日志, logPayEnd用于记录支付结果 logPayBegin(long userId,long money) logPay

Spring的资源详解

一.Spring的资源详解 1.1引言 在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理URL资源.File资源.ClassPath相关资源.服务器相关资源等等很多资源.因此处理这些资源需要使用不同的接口,这就增加了我们系统的复杂性:而且处理这些资源步骤都是类似的(打开资源.读取资源.关闭资源),因此如果能抽象出一个统一的接口来对这些底层资源进行统一访问,是不是很方便,而且使我们系统更加简洁,都是对不同的底层资源使用同一个接口进行访问. Spring提供一个Resource接口来统

spring之ioc详解

第一节:spring IOC的详解 首先想说说IoC(Inversion of Control,控制倒转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好.qq号.电话号.ip号.iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对

一份spring配置文件及其详解

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/axu20/archive/2009/10/14/4668188.aspx 1.基本配置:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/

测试框架mochajs详解

测试框架mochajs详解 章节目录 关于单元测试的想法 mocha单元测试框架简介 安装mocha 一个简单的例子 mocha支持的断言模块 同步代码测试 异步代码测试 promise代码测试 不建议使用箭头函数 钩子函数 钩子函数的描述参数 异步的钩子函数 全局钩子 延迟启动测试 测试用例TODO 仅执行一个用例集/用例 跳过哪些用例集/用例 重新执行用例 动态生成用例 测试时间 测试超时 用例集执行超时 用例执行超时 钩子函数超时 diff差异比较功能 mocha使用命令和参数 mocha

Spring的lazy-init详解

Spring中lazy-init详解ApplicationContext实现的默认行为就是在启动服务器时将所有singleton bean提前进行实例化(也就是依赖注入).提前实例化意味着作为初始化过程的一部分,applicationContext实例会创建并配置所有的singleton bean.通常情况下这是一件好事,因为这样在配置中的任何错误就会被立刻实现(否则的话可能要话几个小时甚至几天). <bean id="testBean" class="cn.itcas