Spring3.0的引入和对rest的支持

Spring3.0的引入和对rest的支持
一、spring主要版本的介绍
1、spring2.0,我们现在使用的版本
环境:支持java1.3+
  ◆引入基于Xml-Schema的配置语法,简化了Xml的配置

  ◆.引入新的Bean作用域(request和session范围)
  ◆.可扩展的容器级Xml配置(Spring官方文档将这个功能上升到了DSL级别

  ◆.AOP有了很大改进,更无缝地整合了AspectJ,为管理Spring容器外的对象提供了可能

  ◆.JdbcTemplate的改进(增加了NamedParameterJdbcTemplate和SimpleJdbcTemplate)
  ◆更简单的事务配置
  ◆.Spring Web MVC的大幅改进和增强(引入了CoC的观点和增强了的标签库)
  ◆.Spring的Scheduling支持引入TaskExecutor抽象
  ◆.支持JPA,支持异步JMS,更好的JMX支持
  ◆.支持动态语言,JRuby,Groovy,BeanShell

2、Spring2.5
环境:支持java1.4+,兼容j2ee1.3
Spring2.5是Spring2.1各个里程碑版本的终结。
Spring2.5是对Spring2.0的增强,增加了一些Spring 2.5新特性:
◆全面支持java6和javaEE5(JDBC 4.0, JTA 1.1, JavaMail 1.4, JAX-WS 2.0等)
◆全特性的注释驱动依赖注入,包括对限定词的支持
◆支持基于classpath的组件扫描,自动侦测有注释的类
◆支持AspectJ切点表达式中包含bean name切点元素
◆内置AspectJ加载时编织,基于LoadTimeWeaver 提取更多的XML配置文件的名字空间支持,比如context和jms等,最大程度提高编写的方便性
◆全面修订集成测试框架,支持JUnit4和TestNG
◆新的基于注释的Servlet MVC和Portlet MVC控制器风格配置
◆扩展SimpleJdbcTemplate功能,支持命名的参数等
◆官方认可的Websphere支持,支持WebSphere 6 UOWManager 机制
◆Spring框架的jar文件,兼容OSGi绑定,并能直接使用
◆Spring ApplicationContext可被部署为JCA RAR文件,用于非主导应用模块
◆JCA 1.5消息终端管理,用于Spring管理的JMS和CCI消息监听器
◆有重要价值的特性为,基于注释的MVC控制器风格,JAX-WS支持和TestNG支持

3、Spring3.0
环境:支持java1.5+
◆Spring表达式语言(简称SpEL):在Bean定义中使用的表达式解析器,可以在属性值中通过#{...}语法,引用嵌套的Bean结构(如其他Bean的属性),就像引用环境数据一样
◆对基于注解的组件的扩展支持:对配置类和注解工厂方法(JavaConfig)的增强,允许用@Value,通过动态表达式#{...},或静态占位符${...},注入配置值。
◆强大的注解模型:允许通过元注解创建“快捷”注解,比如用自定义的注解类别,指代默认的作用域和事务特性。
◆标准化的依赖注入注解:支持Java的依赖注入JSR-330规范,可以用@Inject替代@Autowired。
◆基于注解的声明式模型验证:支持自动发现和配置符合JSR-303规范的Bean验证提供程序(如HiernateValidator4.0)
◆增强的绑定和注解驱动式格式化:格式化可以通过注解驱动,类似JSR-303的约束声明风格。
◆全面的REST支持:SpringMVC内置REST的支持,如REST风格的请求映射,通过@PathVariable参数抽取URI变量,基于内容协商(content negotiation)驱动的视图展示。通过RestTemplate模板类,提供客户端REST支持
◆对象XML映射(OXM):即移入Spring框架核心的Spring Web Services
◆下一代调度支持:新的任务调度器(TaskScheduler)和触发器(Trigger)机制提供一等的cron支持。

In terms of system requirements, Spring 3.0 covers a broad range of environments. For two key characteristics, Spring 3.0 supports Java SE 5 and above and Servlet 2.4 and above, e.g. Tomcat 5.x and 6.x, also retaining compatibility with common enterprise servers such as WebSphere 6.1 and WebLogic 9.2 (which are formally still based on J2EE 1.4). At the same time, we support GlassFish v3 already – adapting to Java EE 6 API level in Spring as well.
As a consequence, Spring 3 brings brand-new component model features, and also standards like JSR-330 injection and JSR-303 validation, to established production environments – without having to upgrade your server installation! All you have to do is to upgrade the application libraries of your Spring-powered application to Spring 3.0…
二、spring3.0的包介绍
1Spring3.0   发现和2.5有了一些变化,没有了Spring.jar的核心包,而是把各个功能的包分开了。如下:
Org.springframework.aop spring的aop实现
Org.springframework.beans springIOC基本实现
Org.springframework.context 在基本ioc上的扩展服务,包括javamail,任务调度,jndi定位,各种视图框架的封装等
Org.springframework.expression spring表达式语言
Org.springframework.jdbc 对jdbc的简单封状
Org.springframework.orm             对orm框架的支持
Org.springframework.transaction 对事务的支持
Org.springframework.web.servlet       springmvc
Spring3.0最基本配置需要一下几个包,看情况而定
org.springframework.asm-3.0.3.RELEASE.jar
org.springframework.beans-3.0.3.RELEASE.jar
org.springframework.context-3.0.3.RELEASE.jar
org.springframework.core-3.0.3.RELEASE.jar
org.springframework.expression-3.0.3.RELEASE.jar
org.springframework.web-3.0.3.RELEASE.jar

三、rest service的介绍
REST(Representational State Transfer)是一种轻量级的Web Service架构风格,其实现和操作明显比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。

REST架构遵循了CRUD原则,CRUD原则对于资源只需要四种行为:Create(创建)、Read(读取)、Update(更新)和Delete(删除)就可以完成对其操作和处理。这四个操作是一种原子操作,即一种无法再分的操作,通过它们可以构造复杂的操作过程,正如数学上四则运算是数字的最基本的运算一样。

REST架构让人们真正理解我们的网络协议HTTP本来面貌,对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法,因此REST把HTTP对一个URL资源的操作限制在GET、POST、PUT和DELETE这四个之内。这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

REST的设计准则
  REST架构是针对Web应用而设计的,其目的是为了降低开发的复杂性,提高系统的可伸缩性。REST提出了如下设计准则:
  网络上的所有事物都被抽象为资源(resource);
  每个资源对应一个唯一的资源标识符(resource identifier);
  通过通用的连接器接口(generic connector interface)对资源进行操作;
  对资源的各种操作不会改变资源标识符;
  所有的操作都是无状态的(stateless




四.Spring3对rest 的支持
springmvc 3.0 中增加 RESTful URL功能,比如
1 /blog/1  HTTP GET =>    得到id = 1的blog 
2 /blog/1  HTTP DELETE => 删除 id = 1的blog 
3 /blog/1  HTTP PUT  =>   更新id = 1的blog 
4 /blog     HTTP POST =>   新增BLOG 

以下详细解一下spring rest使用.

首先,我们带着如下三个问题查看本文。
1. 如何在java构造没有扩展名的RESTful url,如 /forms/1,而不是 /forms/1.do
2. 由于我们要构造没有扩展名的url本来是处理静态资源的容器映射的,现在被我们的spring占用了,冲突怎么解决?
3. 浏览器的form标签不支持提交delete,put请求,如何曲线解决?

springmvc rest 实现
springmvc的resturl是通过@RequestMapping 及@PathVariable annotation提供的,通过如@RequestMapping(value="/blog/{id}",method=RequestMethod.DELETE)即可处理/blog/1 的delete请求.
Java代码

	@RequestMapping(value="/blog/{id}",method=RequestMethod.DELETE)  
	public ModelAndView delete(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) {  
	    blogManager.removeById(id);  
	    return new ModelAndView(LIST_ACTION);  
	} 
  

@RequestMapping @PathVariable如果URL中带参数,则配合使用,如
Java代码
	@RequestMapping(value="/blog/{blogId}/message/{msgId}",method=RequestMethod.DELETE)  
	public ModelAndView delete(@PathVariable("blogId") Long blogId,@PathVariable("msgId") Long msgId,HttpServletRequest request,HttpServletResponse response) {  
	}  
 

spring rest配置指南

1. springmvc web.xml配置
Xml代码
1	<!-- 该servlet为tomcat,jetty等容器提供,将静态资源映射从/改为/static/目录,如原来访问 http://localhost/foo.css ,现在http://localhost/static/foo.css -->  
2	<servlet-mapping>  
3	    <servlet-name>default</servlet-name>  
4	    <url-pattern>/static/*</url-pattern>  
5	</servlet-mapping>  
6	<servlet>  
7	    <servlet-name>springmvc</servlet-name>  
8	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
9	    <load-on-startup>1</load-on-startup>  
10	</servlet>  
11	  
12	<!-- URL重写filter,用于将访问静态资源http://localhost/foo.css 转为http://localhost/static/foo.css -->  
13	<filter>  
14	    <filter-name>UrlRewriteFilter</filter-name>  
15	    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>  
16	    <init-param>  
17	            <param-name>confReloadCheckInterval</param-name>  
18	            <param-value>60</param-value>  
19	        </init-param>  
20	    <init-param>  
21	                <param-name>logLevel</param-name>  
22	                <param-value>DEBUG</param-value>  
23	        </init-param>       
24	</filter>  
25	<filter-mapping>  
26	    <filter-name>UrlRewriteFilter</filter-name>  
27	    <url-pattern>/*</url-pattern>  
28	</filter-mapping>  
29	  
30	<!-- 覆盖default servlet的/, springmvc servlet将处理原来处理静态资源的映射 -->  
31	<servlet-mapping>  
32	    <servlet-name>springmvc</servlet-name>  
33	    <url-pattern>/</url-pattern>  
34	</servlet-mapping>  
35	  
36	<!-- 浏览器不支持put,delete等method,由该filter将/blog?_method=delete转换为标准的http delete方法 --> 
37	<filter>  
38	    <filter-name>HiddenHttpMethodFilter</filter-name>  
39	    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
40	</filter>  
41	  
42	<filter-mapping>  
43	    <filter-name>HiddenHttpMethodFilter</filter-name>  
44	    <servlet-name>springmvc</servlet-name>  
45	</filter-mapping>  
 
2. webapp/WEB-INF/springmvc-servlet.xml配置,使用如下两个class激活@RequestMapping annotation
Java代码
46	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
47	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>  
 

完整配置
Java代码
48	<beans default-autowire="byName"   >  
49	  
50	    <!-- 自动搜索@Controller标注的类 -->  
51	    <context:component-scan base-package="com.**.controller"/>  
52	      
53	    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
54	  
55	    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>  
56	  
57	    <!-- Default ViewResolver -->  
58	    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
59	        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
60	        <property name="prefix" value="/pages"/>  
61	        <property name="suffix" value=".jsp"></property>  
62	    </bean>  
63	      
64	    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="i18n/messages"/>  
65	  
66	    <!-- Mapping exception to the handler view -->  
67	    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
68	        <!-- to /commons/error.jsp -->  
69	        <property name="defaultErrorView" value="/commons/error"/>  
70	        <property name="exceptionMappings">  
71	            <props>  
72	            </props>  
73	        </property>  
74	    </bean>  
75	          
76	</beans>  
 

3. Controller编写
Java代码
77	/** 
78	 * @RequestMapping("/userinfo") 具有层次关系,方法级的将在类一级@RequestMapping之一, 
79	 * 如下面示例, 访问方法级别的@RequestMapping("/new"),则URL为 /userinfo/new 
80	 */  
81	@Controller  
82	@RequestMapping("/userinfo")  
83	public class UserInfoController extends BaseSpringController{  
84	    //默认多列排序,example: username desc,createTime asc  
85	    protected static final String DEFAULT_SORT_COLUMNS = null;   
86	      
87	    private UserInfoManager userInfoManager;  
88	      
89	    private final String LIST_ACTION = "redirect:/userinfo";  
90	      
91	    /**  
92	     * 通过spring自动注入 
93	     **/  
94	    public void setUserInfoManager(UserInfoManager manager) {  
95	        this.userInfoManager = manager;  
96	    }  
97	      
98	    /** 列表 */  
99	    @RequestMapping  
100	    public ModelAndView index(HttpServletRequest request,HttpServletResponse response,UserInfo userInfo) {  
101	        PageRequest<Map> pageRequest = newPageRequest(request,DEFAULT_SORT_COLUMNS);  
102	        //pageRequest.getFilters(); //add custom filters  
103	          
104	        Page page = this.userInfoManager.findByPageRequest(pageRequest);  
105	        savePage(page,pageRequest,request);  
106	        return new ModelAndView("/userinfo/list","userInfo",userInfo);  
107	    }  
108	      
109	    /** 进入新增 */  
110	    @RequestMapping(value="/new")  
111	    public ModelAndView _new(HttpServletRequest request,HttpServletResponse response,UserInfo userInfo) throws Exception {  
112	        return new ModelAndView("/userinfo/new","userInfo",userInfo);  
113	    }  
114	      
115	    /** 显示 */  
116	    @RequestMapping(value="/{id}")  
117	    public ModelAndView show(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception {  
118	        UserInfo userInfo = (UserInfo)userInfoManager.getById(id);  
119	        return new ModelAndView("/userinfo/show","userInfo",userInfo);  
120	    }  
121	      
122	    /** 编辑 */  
123	    @RequestMapping(value="/{id}/edit")  
124	    public ModelAndView edit(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception {  
125	        UserInfo userInfo = (UserInfo)userInfoManager.getById(id);  
126	        return new ModelAndView("/userinfo/edit","userInfo",userInfo);  
127	    }  
128	      
129	    /** 保存新增 */  
130	    @RequestMapping(method=RequestMethod.POST)  
131	    public ModelAndView create(HttpServletRequest request,HttpServletResponse response,UserInfo userInfo) throws Exception {  
132	        userInfoManager.save(userInfo);  
133	        return new ModelAndView(LIST_ACTION);  
134	    }  
135	      
136	    /** 保存更新 */  
137	    @RequestMapping(value="/{id}",method=RequestMethod.PUT)  
138	    public ModelAndView update(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) throws Exception {  
139	        UserInfo userInfo = (UserInfo)userInfoManager.getById(id);  
140	        bind(request,userInfo);  
141	        userInfoManager.update(userInfo);  
142	        return new ModelAndView(LIST_ACTION);  
143	    }  
144	      
145	    /** 删除 */  
146	    @RequestMapping(value="/{id}",method=RequestMethod.DELETE)  
147	    public ModelAndView delete(@PathVariable Long id,HttpServletRequest request,HttpServletResponse response) {  
148	        userInfoManager.removeById(id);  
149	        return new ModelAndView(LIST_ACTION);  
150	    }  
151	  
152	    /** 批量删除 */  
153	    @RequestMapping(method=RequestMethod.DELETE)  
154	    public ModelAndView batchDelete(@RequestParam("items") Long[] items,HttpServletRequest request,HttpServletResponse response) {  
155	          
156	        for(int i = 0; i < items.length; i++) {  
157	              
158	            userInfoManager.removeById(items[i]);  
159	        }  
160	        return new ModelAndView(LIST_ACTION);  
161	    }  
162	      
163	}  
 
Java代码
1 /userinfo           => index() 
2 /userinfo/new       => _new() 
3 /userinfo/{id}      => show() 
4 /userinfo/{id}/edit         => edit() 
5 /userinfo   POST        => create() 
6 /userinfo/{id}  PUT => update() 
7 /userinfo/{id}  DELETE  => delete() 
8 /userinfo   DELETE      => batchDelete() 
注(不使用 /userinfo/add  => add() 方法是由于add这个方法会被maxthon浏览器当做广告链接过滤掉,因为包含ad字符)
4. jsp 编写
Html代码
1 <form:form action="${ctx}/userinfo/${userInfo.userId}" method="put"> 
2 </form:form> 
生成的html内容如下, 生成一个hidden的_method=put,并于web.xml中的HiddenHttpMethodFilter配合使用,在服务端将post请求改为put请求
Java代码
3 <form id="userInfo" action="/springmvc_rest_demo/userinfo/2" method="post"> 
4     <input type="hidden" name="_method" value="put"/> 
5 </form> 

另外一种方法是你可以使用ajax发送put,delete请求.
5. 静态资源的URL重写
   如上我们描述,现因为将default servlet映射至/static/的子目录,现我们访问静态资源将会带一个/static/前缀.
   如 /foo.gif, 现在访问该文件将是 /static/foo.gif.
   那如何避免这个前缀呢,那就是应用URL rewrite,现我们使用 http://tuckey.org/urlrewrite/, 重写规则如下

Xml代码
1	<urlrewrite>  
2	    <!-- 访问jsp及jspx将不rewrite url,其它.js,.css,.gif等将重写,如 /foo.gif => /static/foo.gif -->  
3	    <rule>  
4	        <condition operator="notequal" next="and" type="request-uri">.*.jsp</condition>  
5	        <condition operator="notequal" next="and" type="request-uri">.*.jspx</condition>  
6	        <from>^(/.*\..*)$</from>  
7	        <to>/static$1</to>  
8	    </rule>  
9	</urlrewrite>  
 


猜你喜欢

转载自wyq756543431.iteye.com/blog/1333576
今日推荐