`
zzc1684
  • 浏览: 1190496 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

Spring4新特性——Web开发的增强

阅读更多

从Spring4开始,Spring以Servlet3为进行开发,如果用Spring MVC 测试框架的话需要指定Servlet3兼容的jar包(因为其Mock的对象都是基于Servlet3的)。另外为了方便Rest开发,通过新的 @RestController指定在控制器上,这样就不需要在每个@RequestMapping方法上加 @ResponseBody了。而且添加了一个AsyncRestTemplate ,支持REST客户端的异步无阻塞支持。

 

1、@RestController

Java代码  收藏代码
  1. @RestController  
  2. public class UserController {  
  3.     private UserService userService;  
  4.     @Autowired  
  5.     public UserController(UserService userService) {  
  6.         this.userService = userService;  
  7.     }  
  8.     @RequestMapping("/test")  
  9.       public User view() {  
  10.         User user = new User();  
  11.         user.setId(1L);  
  12.         user.setName("haha");  
  13.         return user;  
  14.     }  
  15.   
  16.     @RequestMapping("/test2")  
  17.     public String view2() {  
  18.         return "{\"id\" : 1}";  
  19.     }  
  20. }  

 其实现就是在@@RestController中加入@ResponseBody:

Java代码  收藏代码
  1. @org.springframework.stereotype.Controller  
  2. @org.springframework.web.bind.annotation.ResponseBody  
  3. public @interface RestController {  
  4. }  

这样当你开发Rest服务器端的时候,spring-mvc配置文件需要的代码极少,可能就仅需如下一行:

Java代码  收藏代码
  1. <context:component-scan base-package="com.sishuok.spring4"/>  
  2. <mvc:annotation-driven/>  

  

2、mvc:annotation-driven配置变化

统一风格;将 enableMatrixVariables改为enable-matrix-variables属性;将ignoreDefaultModelOnRedirect改为ignore-default-model-on-redirect。

 

3、提供AsyncRestTemplate用于客户端非阻塞异步支持。

3.1、服务器端

对于服务器端的springmvc开发可以参考https://github.com/zhangkaitao/servlet3-showcase中的chapter3-springmvc

Java代码  收藏代码
  1. @RestController  
  2. public class UserController {  
  3.     private UserService userService;  
  4.     @Autowired  
  5.     public UserController(UserService userService) {  
  6.         this.userService = userService;  
  7.     }  
  8.     @RequestMapping("/api")  
  9.       public Callable<User> api() {  
  10.         System.out.println("=====hello");  
  11.         return new Callable<User>() {  
  12.             @Override  
  13.             public User call() throws Exception {  
  14.                 Thread.sleep(10L * 1000); //暂停两秒  
  15.                 User user = new User();  
  16.                 user.setId(1L);  
  17.                 user.setName("haha");  
  18.                 return user;  
  19.             }  
  20.         };  
  21.     }  
  22. }  

非常简单,服务器端暂停10秒再返回结果(但是服务器也是非阻塞的)。具体参考我github上的代码。

 

3.2、客户端

Java代码  收藏代码
  1. public static void main(String[] args) {  
  2.     AsyncRestTemplate template = new AsyncRestTemplate();  
  3.     //调用完后立即返回(没有阻塞)  
  4.     ListenableFuture<ResponseEntity<User>> future = template.getForEntity("http://localhost:9080/spring4/api", User.class);  
  5.     //设置异步回调  
  6.     future.addCallback(new ListenableFutureCallback<ResponseEntity<User>>() {  
  7.         @Override  
  8.         public void onSuccess(ResponseEntity<User> result) {  
  9.             System.out.println("======client get result : " + result.getBody());  
  10.         }  
  11.   
  12.         @Override  
  13.         public void onFailure(Throwable t) {  
  14.             System.out.println("======client failure : " + t);  
  15.         }  
  16.     });  
  17.     System.out.println("==no wait");  
  18. }  

 此处使用Future来完成非阻塞,这样的话我们也需要给它一个回调接口来拿结果; Future和Callable是一对,一个消费结果,一个产生结果。调用完模板后会立即返回,不会阻塞;有结果时会调用其回调。

 

AsyncRestTemplate默认使用SimpleClientHttpRequestFactory,即通过 java.net.HttpURLConnection实现;另外我们也可以使用apache的http components;使用template.setAsyncRequestFactory(new HttpComponentsAsyncClientHttpRequestFactory());设置即可。

 

另外在开发时尽量不要自己注册如:

Java代码  收藏代码
  1. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>  
  2. <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">  

尽量使用

Java代码  收藏代码
  1. <mvc:annotation-driven/>   

它设计的已经足够好,使用子元素可以配置我们需要的配置。

  

且不要使用老版本的:

Java代码  收藏代码
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
  2. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  

否则可能得到如下异常:

写道
Circular view path [login]: would dispatch back to the current handler URL [/spring4/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

 

评论

24 楼 lokepaqi 2014-07-25   引用
contrarotate 写道
z19910509 写道
涛 哥,使用了 @RestController 注解后就只能返回json数据吗,我想返回一个视图,比如说index.jsp 还可以吗,试了下 只返回一个字符串 index

试试返回ModelAndView?

我也遇到过这问题,应该是因为 使用@ResponseBody将会跳过视图处理部分,而是调用适合HttpMessageConverter,将返回值写入输出流。
23 楼 jacking124 2014-07-10   引用
张哥,在android客户端请求的时候返回json出现406错误!!
22 楼 contrarotate 2014-06-16   引用
z19910509 写道
涛 哥,使用了 @RestController 注解后就只能返回json数据吗,我想返回一个视图,比如说index.jsp 还可以吗,试了下 只返回一个字符串 index

试试返回ModelAndView?
21 楼 z19910509 2014-04-04   引用
涛 哥,使用了 @RestController 注解后就只能返回json数据吗,我想返回一个视图,比如说index.jsp 还可以吗,试了下 只返回一个字符串 index
20 楼 dieslrae 2013-12-18   引用
jinnianshilongnian 写道
dieslrae 写道
jinnianshilongnian 写道
kangaroo_xin 写道
jinnianshilongnian 写道
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@ResponseBody 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

这些都是我测试通过之后才写的

直接写
Xml代码  收藏代码
  1. <mvc:annotation-driven/>  

没有问题,但是换成这样下面这种写法之后就会报错了
Xml代码  收藏代码
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
  2.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  3.         <property name="messageConverters">  
  4.             <list>  
  5.                 <ref bean="mappingJacksonHttpMessageConverter"/>  
  6.             </list>  
  7.         </property>  
  8.     </bean>  
  9.       
  10.     <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  11.         <property name="supportedMediaTypes">  
  12.             <list>  
  13.                 <value>text/html;charset=UTF-8</value>  
  14.             </list>  
  15.         </property>  
  16.     </bean>  


提示这个错
Java代码  收藏代码
  1. Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)  

估计是你哪个地配置的不对,MappingJacksonHttpMessageConverter升级到MappingJackson2HttpMessageConverter吧,(需要jackson2版本)

Circular view path [login]: would dispatch back to the current handler URL [/login] again

从错误看访问login好像死循环了;估计不是这段代码的问题;可能是其他配置的问题;如果方便把相关配置文件站内信我

晚上回家发你
19 楼 jinnianshilongnian 2013-12-18   引用
dieslrae 写道
jinnianshilongnian 写道
kangaroo_xin 写道
jinnianshilongnian 写道
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@ResponseBody 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

这些都是我测试通过之后才写的

直接写
Xml代码  收藏代码
  1. <mvc:annotation-driven/>  

没有问题,但是换成这样下面这种写法之后就会报错了
Xml代码  收藏代码
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
  2.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  3.         <property name="messageConverters">  
  4.             <list>  
  5.                 <ref bean="mappingJacksonHttpMessageConverter"/>  
  6.             </list>  
  7.         </property>  
  8.     </bean>  
  9.       
  10.     <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  11.         <property name="supportedMediaTypes">  
  12.             <list>  
  13.                 <value>text/html;charset=UTF-8</value>  
  14.             </list>  
  15.         </property>  
  16.     </bean>  


提示这个错
Java代码  收藏代码
  1. Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)  

估计是你哪个地配置的不对,MappingJacksonHttpMessageConverter升级到MappingJackson2HttpMessageConverter吧,(需要jackson2版本)

Circular view path [login]: would dispatch back to the current handler URL [/login] again

从错误看访问login好像死循环了;估计不是这段代码的问题;可能是其他配置的问题;如果方便把相关配置文件站内信我
18 楼 dieslrae 2013-12-17   引用
jinnianshilongnian 写道
kangaroo_xin 写道
jinnianshilongnian 写道
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@ResponseBody 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

这些都是我测试通过之后才写的

直接写
Xml代码  收藏代码
  1. <mvc:annotation-driven/>  

没有问题,但是换成这样下面这种写法之后就会报错了
Xml代码  收藏代码
  1. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
  2.     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
  3.         <property name="messageConverters">  
  4.             <list>  
  5.                 <ref bean="mappingJacksonHttpMessageConverter"/>  
  6.             </list>  
  7.         </property>  
  8.     </bean>  
  9.       
  10.     <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
  11.         <property name="supportedMediaTypes">  
  12.             <list>  
  13.                 <value>text/html;charset=UTF-8</value>  
  14.             </list>  
  15.         </property>  
  16.     </bean>  


提示这个错
Java代码  收藏代码
  1. Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)  
17 楼 jinnianshilongnian 2013-12-16   引用
pipinet 写道
楼主不知道有没有关于websocket的配置分析呢?

后续有时间的话想试试,然后分析;这个要看业余时间是否充分了
16 楼 pipinet 2013-12-16   引用
楼主不知道有没有关于websocket的配置分析呢?
15 楼 jinnianshilongnian 2013-12-15   引用
kangaroo_xin 写道
jinnianshilongnian 写道
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@ResponseBody 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

这些都是我测试通过之后才写的
14 楼 jinnianshilongnian 2013-12-15   引用
kangaroo_xin 写道
jinnianshilongnian 写道
kangaroo_xin 写道
另外 AsyncRestTemplate 使用必须使用 application/json 返回json

如果使用text/html会报,无法转换成User对象。

嗯,它在请求时会带着Accept:application/json, application/*+json 过去;springmvc会自动响应Content-Type:application/json;

估计是不是你没加 jackson2的jar包?

因为IE下用 application/json 返回json,会发生弹出下载框的情况,所以一般我都定义成text/html返回json。 这样和AsyncRestTemplate 有点冲突了

这个倒不影响 可以写个filter判断下是客户端的 还是浏览器过来的 针对ie单独设置响应头
13 楼 kangaroo_xin 2013-12-15   引用
jinnianshilongnian 写道
kangaroo_xin 写道
另外 AsyncRestTemplate 使用必须使用 application/json 返回json

如果使用text/html会报,无法转换成User对象。

嗯,它在请求时会带着Accept:application/json, application/*+json 过去;springmvc会自动响应Content-Type:application/json;

估计是不是你没加 jackson2的jar包?

因为IE下用 application/json 返回json,会发生弹出下载框的情况,所以一般我都定义成text/html返回json。 这样和AsyncRestTemplate 有点冲突了
12 楼 kangaroo_xin 2013-12-15   引用
jinnianshilongnian 写道
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}

@ResponseBody 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗
11 楼 jinnianshilongnian 2013-12-15   引用
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。


这是@RestController注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

}
10 楼 jinnianshilongnian 2013-12-15   引用
kangaroo_xin 写道
另外 AsyncRestTemplate 使用必须使用 application/json 返回json

如果使用text/html会报,无法转换成User对象。

嗯,它在请求时会带着Accept:application/json, application/*+json 过去;springmvc会自动响应Content-Type:application/json;

估计是不是你没加 jackson2的jar包?
9 楼 jinnianshilongnian 2013-12-15   引用
kangaroo_xin 写道
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。

不用配其他的啊;@RestController = @Controller + @ResponseBody
8 楼 kangaroo_xin 2013-12-14   引用
另外 AsyncRestTemplate 使用必须使用 application/json 返回json

如果使用text/html会报,无法转换成User对象。
7 楼 kangaroo_xin 2013-12-14   引用
@RestController

配置后为什么不起作用呢?哪里还需要配置

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。
6 楼 jinnianshilongnian 2013-12-14   引用
angelxdb 写道
jinnianshilongnian 写道
angelxdb 写道
支持支持,,楼主3.2以后已经不推荐XML 配置了,希望楼主多说说类配置

一直没听过这个说法,出处在哪,我去瞅瞅学习下;我认为xml配置还是不能替代的;类配置在之前的跟我学spring3里有一部分。

http://spring.io/guides/tutorials/web/3/ 你看这个例子

嗯,如果spring3.2开始不推荐xml了的话,spring4就没必要出goovy bean定义 dsl了;在很多时候配置文件还是很灵活的,比如aop配置时;
5 楼 angelxdb 2013-12-14   引用
jinnianshilongnian 写道
angelxdb 写道
支持支持,,楼主3.2以后已经不推荐XML 配置了,希望楼主多说说类配置

一直没听过这个说法,出处在哪,我去瞅瞅学习下;我认为xml配置还是不能替代的;类配置在之前的跟我学spring3里有一部分。

http://spring.io/guides/tutorials/web/3/ 你看这个例子
分享到:
评论

相关推荐

    Spring4.x企业应用开发 有书签,很方便查找

    pring 4.0是Spring在积蓄4年后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域*开源平台的翘楚地位。Spring 4.0引入了众多Java开发者翘首以盼的基于Groovy Bean的配置、HTML 5/WebSocket支持等新功能...

    Spring3.x企业应用开发实战

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part03

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part02.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part06.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part05.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part04.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x 企业应用开发实战[光盘].part01.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x企业应用开发实战[完整版+书签].part2.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring 3.x企业应用开发实战[完整版+书签].part1.rar

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring+3.x+企业应用开发实践(2)

    Spring 3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用开发的难度,同时有效提升...

    Spring.3.x企业应用开发实战(完整版).part2

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    Spring3.x企业应用开发实战(完整版) part1

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    1.2.4 Android移动Web项目开发的三种解决方案:Native, Web和Hybrid优缺陷分析 4 1.2.5国内外应用现状 6 1.2.6 研究现状总结 7 1.3研究目标与内容 7 1.3.1多窗口浏览器模式的实现机制 7 1.3.2跨域交互即缓存处理方法...

    深入浅出struts2

    Struts2的目标很简单——使Web开发变得更加容易。为了达成这一目标,Struts2中提供了很多新特性,比如智能的默认设置、annotation的使用以及“惯例重于配置”原则的应用,而这一切都大大减少了XML配置。Struts2中的...

    asp.net知识库

    Web开发: 使用URL重写WEB主题切换 如何在Asp.Net1.1中实现页面模板(所谓的MasterPage技术) Tool Tip 示例(FILTER版) Tool Tip示例 (htc版) 一个.net发送HTTP数据实体的类 按键跳转以及按Enter以不同参数提交,及...

    webx3框架指南PDF教程附学习Demo

    • 扩展性 —— Webx 3.0对Spring做了扩展,使Spring Bean不再是“bean”,而是升级成“组件”。一个组件可以扩展另一个组件,也可以被其它组件扩展。这种机制造就了Webx的非常好的扩展性,且比未经扩展的Spring更易...

    iuhyiuhkjh908u0980

    logo 设计不会,就这样先凑合了写道 Fuseblog预备开发带在线SHOP功能的个人博客系统.仿照Appfuse 提供一个完全自动化的ant构建脚本.在线SHOP的数据库建模图例已经 在博客中贴出.感兴趣的和我一起搭建,嘻嘻 文档博客...

    JAVA上百实例源码以及开源项目

    此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...

Global site tag (gtag.js) - Google Analytics