码迷,mamicode.com
首页 > 编程语言 > 详细

Spring框架:SpringMVC详解

时间:2014-10-12 00:18:17      阅读:469      评论:0      收藏:0      [点我收藏+]

标签:springmvc   java   web框架   spring mvc   spring   

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

bubuko.com,布布扣


基本配置

声明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字段。

Spring框架:SpringMVC详解

标签:springmvc   java   web框架   spring mvc   spring   

原文地址:http://blog.csdn.net/caipeichao2/article/details/40000219

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!