Spring MVC 3.0深入

Spring MVC 3.0深入
2010.12.14

一、核心原理

1、用户发送请求给服务器,url:user.do
2、服务器收到请求。发现DispatchServlet可以处理。于是调用DispatchServlet。
3、DispatchServlet内部,通过HandlerMapping检查这个url有没有对应的Controller,如果有,则调用Controller。如果没有,则报404。
4、Controller开始执行。
5、Controller执行完毕后,如果返回字符串,则ViewResolver将字符串转化成响应的视图对象;如果返回ModelAndVIew对象,该对象本身就包含了视图对象信息。
6、DispatchServlet将执行视图对象中的数据,输出给服务器。
7、服务器将数据输出给客户端。
8、ViewResolver视图解析器,比如:return "index",通过ViewResolver会把它指向到相关的jsp上(index.jsp)。

二、ModelAndView模型视图类

从名字上我们可以知道ModelAndView中的Model代表模型,View代表视图。即这个类把要显示的数据存储到了Model属性中,要跳转的视图存储到了View属性中。

如下所示:
@Controller
@RequestMapping("/user.do")
public class UserController extends MultiActionController {

    @RequestMapping(params="method=reg")
    public ModelAndView reg(String uname) {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("index"); //设定视图
        //mv.setView(new RedirectView("index");
        User u = new User();
        u.setUname("高淇");
        mv.addObject(u); //查看源代码得知,直接放入对象。属性名为首字母小写的类名。一般建议手动增加属性名称。
        mv.addObject("a", "aaaa");
        return mv;
    }

}
ModelAndView默认放入ModelMap里面,即放入了request里面,所以从request里取。
使用:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
</head>
<body>
    <h1>${requestScope.a}</h1>
    <h2>${requestScope.user.uname}</h1>
</body>
</html>

三、Spring MVC相关注解

1、@Controller控制器定义
和struts1一样,Spring的Controller是Singleton(单例)的。这就意味着会被多个请求线程共享。因此,我们将控制器设计成无状态类。

在Spring MVC 3.0中,通过@Controller注解,即可将class定义为一个Controller类。为使Spring能找到定义为Controller的bean,需要在spring-context配置文件中增加如下定义(配置自动扫描):
<context:component-scan base-package="com.bjsxt.web"/>
注:实际上,使用@Component,也可以起到@Controller同样的作用。

2、@RequestMapping
在类前面定义,则将url和类绑定。
在方法的前面定义,则将url和类的方法绑定,如下所示:
@Controller
@RequestMapping("/user.do")
public class UserController {
......

    @RequestMapping(params="method=reg")
    public String reg(String uname) {
    ......
    }
}
如果访问:http://xxx/user.do,则会跑到UserController类里面,至于调用哪个方法,url里面需携带一个参数。
如果访问:http://xxx/user.do?method=reg,则指向reg方法。

参考:http://blog.csdn.net/J080624/article/details/55193269

3、@RequestParam
一般用于将指定的请求参数赋值给方法中形参。如下示例:
@RequestMapping(params="method=reg5")
public String reg5(@RequestParam("name")String uname, ModelMap map) {
......
}
表单提交里叫name,方法里叫uname。@RequestParam注解可以用来提取名为“name”的String类型的参数,并将之作为输入参数传入方法里的uname。

这样,就会将name参数的值赋给uname。当然,如果请求参数名称和形参名称保持一致,就不需要这种写法。

4、@SessionAttributes
将ModelMap中指定的属性放到session中。
ModelMap说明见下面的“四、ModelMap”。

如下所示:
@Controller
@RequestMapping("/user.do")
@SessionAttributes({"u", "a"}) //将ModelMap中属性名字为u、a的再放入session中。这样,request和session中都有了。
public class UserController {
    @RequestMapping(params="method=reg4")
    public String reg4(ModelMap map) {
        System.out.println("HelloController.handlerRequest()");
        map.addAttribute("u", "uuuu"); //map里放入u属性,同时也会放入session中。在request作用域中有,session里也有,这样转发页面也可以取到这个数据
        return "index";
    }
}
5、@ModelAttribute
这个注解可以跟@SessionAttributes配合在一起用。可以将ModelMap中属性的值通过该注解自动赋给指定的变量(先放入session中,再从session中取出来)。

如下所示:
@RequestMapping(params="method=reg5")
public String reg5(@ModelAttribute("u")String uname, ModelMap map) {
    System.out.println(uname);
    return "index";
}
直接把ModelMap中的值u,赋到uname上。

四、ModelMap

是Map的实现,可以在其中存放属性,作用域同request。我们可以在ModelMap中放入数据,然后在forward的页面上显示这些数据。通过el表达式、JSTL、java代码均可。

如何获取这个ModelMap,只要在方法里写一个形参ModelMap map就行了,Spring看到你有这个参数,会自动创建一个ModelMap,给你传进来。

方法的形参,只要Spring IoC容器里有的,直接帮你把引用赋过来。

如下所示:
@RequestMapping(params="method=reg3")
public String reg3(@RequestParam("uname") String name, ModelMap map) {
    System.out.println("UserController.reg3()");
    System.out.println(name);
    map.put("a", "aaa");
    return "index";
}

//然后在页面上取出a的值

五、参数和返回值的处理

1、Controller类中方法参数的处理
直接往里写就完了。

2、Controller类中方法返回值的处理
1)返回String(建议)
    a)根据返回值找对应的显示页面。路径规则为:prefix前缀 + 返回值 + suffix后缀组成
    b)代码如下:
@RequestMapping(params="method=reg4")
public String reg4(ModelMap map) {
    System.out.println("HelloController.handleRequest()");
    return "index";
}
前缀为:/WEB-INF/jsp/    后缀为:.jsp
再转发到:/WEB-INF/jsp/index.jsp

2、也可以返回ModelMap、ModelAndView、map、List、Set、Object、无返回值,一般建议返回字符串!

六、获得request对象,session对象

request对象:声明形参HttpServletRequest req
session对象:通过request获得,req.getSession();

七、请求转发和重定向

转发:return "index";
转发:return "forward:user.do?method=reg5";
重定向:return "redirect:http://www.baidu.com";

八、基于Spring3.0mvc框架的文件上传实现

1、Spring使用了apache-commons下的上传组件,因此,我们需要引入两个jar包:
apache-commons-fileupload.jar
apache-commons-io.jar

在springmvc-servlet.xml配置文件中,增加CommonsMultiPartResolver配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!--默认编码-->
	<property name="defaultEncoding" value="utf-8" />
	<!--最大文件大小-->
	<property name="maxUploadSize" value="10485760000" />
	<!--最大内存大小-->
	<property name="maxInMemorySize" value="40960" />
	<!--上传后的目录名-->
	<property name="uploadTempDir" value="/upload/" />
</bean>
上传页面upload.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<html>
<head>
	<title>测试springmvc中上传的实现<title>
</head>
<body>
	<form action="upload.do" method="post" enctype="multipart/form-date">
	<input type="text" name="name" />
	<input type="file" name="file" />
	<input type="submit" />
	</form>
</body>
</html>
控制器:

九、处理ajax请求

spring使用了jackson类库,帮助我们在java对象和json、xml数据之间的互相转换。他可以将控制器返回的对象直接转换成json数据,供客户端使用。客户端也可以传送json数据到服务器进行直接转换。

1、项目中需要引入如下两个jar包:
jackson-core-asl-1.7.2.jar
jackson-mapper-asl-1.7.2.jar

2、spring配置文件中增加:
<!--开启mvc注解驱动-->
<mvc:annotation-driven/>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
	<property name="messageConverters">
	<list>
		<!-- <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> 2.x中已过时 -->
		<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
		<bean class="org.springframework.http.converter.StringHttpMessageConverter">
			<property name="supportedMediaTypes">
			<list>
				<value>text/plain; charset=UTF-8</value>
			</list>
			</property>
		</bean>
	</list>
	</property>
</bean>
控制器:
@Controller
@RequestMapping("myajax.do")
public class MyAjaxController {
	@RequestMapping(params="method=test1", method=RequestMethod.GET)
	public @ResponseBody List<User> test1(String uname) throws Exception {
		String uname2 = new String(uname.getBytes("iso-8859-1"), "gbk");
		System.out.println(uname2);
		List<User> list = new ArrayList<User>();
		list.add(new User("高淇", "123");
		list.add(new User("马士兵", "456");

		return list;
	}
}
如果是ajax域,在方法名前加@ResponseBody。返回数据类型可以是任何类型。spring帮你自动转为json数据。

PS:@RestController注解相当于@ResponseBody + @Controller合在一起的作用,此时无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是return里的内容。

3、<mvc:annotation-driven/>的作用
http://blog.csdn.net/qq_18675693/article/details/52214056

spring 3.1 开始我们应该用
RequestMappingHandlerMapping来替换DefaultAnnotationHandlerMapping,
用RequestMappingHandlerAdapter来替换AnnotationMethodHandlerAdapter。

十、Spring中的拦截器

拦截器拦截的是spring接收到的请求。

1、定义spring拦截器两种基本方式
方法一:
实现接口org.springframework.web.servlet.HandlerInterceptor,接口中有如下方法需要重写:
package org.springframework.web.servlet;
	public interface HandlerInterceptor {
		boolean preHandle(
			HttpServletRequest request, HttpServletResponse response,
			Object handler)
			throws Exception;

		void postHandle(
			HttpServletRequest request, HttpServletResponse response,
			Object handler, ModelAndView modelAndView)
			throws Exception;

		void afterCompletion(
			HttpServletRequest request, HttpServletResponse response,
			Object handler, Exception ex)
			throws Exception;
	}
注意:参数中的Object handler是下一个拦截器。

a)preHandle方法
该方法在action执行前执行,可以实现对数据的预处理,比如:编码、安全控制等。如果方法返回true,则继续执行action。

b)postHandle方法
该方法在action执行后,生成视图前执行。在这里,我们有机会修改视图层数据。

c)afterCompletion方法
最后执行,通常用于释放资源,处理异常。我们可以根据ex是否为空,来进行相关的异常处理。因为我们在平时处理异常时,都是从底层向上抛出异常,最后到了spring框架从而到了这个方法中。

2、继承适配器
方法二:继承org.springframework.web.servlet.handler.HandlerInterceptorAdapter类
这个适配器实现了HandlerInterceptorAdapter接口,提供了这个接口中所有方法的空实现。

这样不想实现的方法不用重写。

参考资料:http://jinnianshilongnian.iteye.com/blog/1670856/

3、xml中配置拦截器
<mvc:interceptors>
    <!--拦截所有springmvc的url-->
    <bean class="com.bjsxt.interceptor.MyInterceptor1"></bean>
</mvc:interceptors>
<mvc:interceptors>
    <!--拦截指定的请求-->
    <mvc:interceptor>
        <mvc:mapping path="/user.do" />
        <mvc:mapping path="/user2.do" />
        <bean class="com.bjsxt.interceptor.MyInterceptor2"></bean>
    </mvc:interceptor>
</mvc:interceptors>
参考资料:http://blog.csdn.net/tong_xinglong/article/details/52035131

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值