您的位置:首页 > 编程语言 > Java开发

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

2012-05-07 17:22 204 查看


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

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

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

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

Xml代码  



46  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>    

47  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>    

 

完整配置

Java代码 

Xml代码  



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

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

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> 
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息