当前位置: 代码迷 >> Web前端 >> Spring4新特性――Web开发的加强
  详细解决方案

Spring4新特性――Web开发的加强

热度:702   发布时间:2013-12-19 00:33:34.0
Spring4新特性――Web开发的增强

Spring4新特性――泛型限定式依赖注入

Spring4新特性――核心容器的其他改进

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

Spring4新特性――集成Bean Validation 1.1(JSR-349)到SpringMVC

?

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

?

1、@RestController

@RestController
public class UserController {
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    @RequestMapping("/test")
      public User view() {
        User user = new User();
        user.setId(1L);
        user.setName("haha");
        return user;
    }

    @RequestMapping("/test2")
    public String view2() {
        return "{\"id\" : 1}";
    }
}

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

@org.springframework.stereotype.Controller
@org.springframework.web.bind.annotation.ResponseBody
public @interface RestController {
}

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

    <context:component-scan base-package="com.sishuok.spring4"/>
    <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

@RestController
public class UserController {
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    @RequestMapping("/api")
      public Callable<User> api() {
        System.out.println("=====hello");
        return new Callable<User>() {
            @Override
            public User call() throws Exception {
                Thread.sleep(10L * 1000); //暂停两秒
                User user = new User();
                user.setId(1L);
                user.setName("haha");
                return user;
            }
        };
    }
}

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

?

3.2、客户端

    public static void main(String[] args) {
        AsyncRestTemplate template = new AsyncRestTemplate();
        //调用完后立即返回(没有阻塞)
        ListenableFuture<ResponseEntity<User>> future = template.getForEntity("http://localhost:9080/spring4/api", User.class);
        //设置异步回调
        future.addCallback(new ListenableFutureCallback<ResponseEntity<User>>() {
            @Override
            public void onSuccess(ResponseEntity<User> result) {
                System.out.println("======client get result : " + result.getBody());
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("======client failure : " + t);
            }
        });
        System.out.println("==no wait");
    }

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

?

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

?

?

1 楼 manong_java 2013-12-14  
顶不错  昨天刚看了文档 不过英文不太好 看了你的翻译 明白了 多谢tao哥
2 楼 jinnianshilongnian 2013-12-14  
manong_java 写道
顶不错  昨天刚看了文档 不过英文不太好 看了你的翻译 明白了 多谢tao哥

翻译下 给个例子   哪不明白可以交流
3 楼 angelxdb 2013-12-14  
支持支持,,楼主3.2以后已经不推荐XML 配置了,希望楼主多说说类配置
4 楼 jinnianshilongnian 2013-12-14  
angelxdb 写道
支持支持,,楼主3.2以后已经不推荐XML 配置了,希望楼主多说说类配置

一直没听过这个说法,出处在哪,我去瞅瞅学习下;我认为xml配置还是不能替代的;类配置在之前的跟我学spring3里有一部分。
5 楼 angelxdb 2013-12-14  
jinnianshilongnian 写道
angelxdb 写道
支持支持,,楼主3.2以后已经不推荐XML 配置了,希望楼主多说说类配置

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

http://spring.io/guides/tutorials/web/3/ 你看这个例子
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配置时;
7 楼 kangaroo_xin 2013-12-14  
@RestController

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

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。
8 楼 kangaroo_xin 2013-12-14  
另外 AsyncRestTemplate 使用必须使用 application/json 返回json

如果使用text/html会报,无法转换成User对象。
9 楼 jinnianshilongnian 2013-12-15  
kangaroo_xin 写道
@RestController

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

已经使用了spring 4.0.0的包了

使用@Controller 和 @ResponseBody 可以。

不用配其他的啊;@RestController = @Controller + @ResponseBody
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包?
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 {

}
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 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗
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 有点冲突了
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单独设置响应头
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 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

这些都是我测试通过之后才写的
16 楼 pipinet 前天  
楼主不知道有没有关于websocket的配置分析呢?
17 楼 jinnianshilongnian 前天  
pipinet 写道
楼主不知道有没有关于websocket的配置分析呢?

后续有时间的话想试试,然后分析;这个要看业余时间是否充分了
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 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

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

直接写
 <mvc:annotation-driven/>

没有问题,但是换成这样下面这种写法之后就会报错了
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name="messageConverters">
    		<list>
    			<ref bean="mappingJacksonHttpMessageConverter"/>
    		</list>
    	</property>
    </bean>
    
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean>


提示这个错
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.)
19 楼 jinnianshilongnian 15 小时前  
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 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

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

直接写
 <mvc:annotation-driven/>

没有问题,但是换成这样下面这种写法之后就会报错了
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name="messageConverters">
    		<list>
    			<ref bean="mappingJacksonHttpMessageConverter"/>
    		</list>
    	</property>
    </bean>
    
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean>


提示这个错
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好像死循环了;估计不是这段代码的问题;可能是其他配置的问题;如果方便把相关配置文件站内信我
20 楼 dieslrae 13 小时前  
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 放在函数方法上可以,放在类上无效。

您那有这个的测试工程吗

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

直接写
 <mvc:annotation-driven/>

没有问题,但是换成这样下面这种写法之后就会报错了
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    	<property name="messageConverters">
    		<list>
    			<ref bean="mappingJacksonHttpMessageConverter"/>
    		</list>
    	</property>
    </bean>
    
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
    </bean>


提示这个错
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好像死循环了;估计不是这段代码的问题;可能是其他配置的问题;如果方便把相关配置文件站内信我

晚上回家发你
  相关解决方案