文档章节

Spring4.1新特性——Spring MVC增强

莱茵河水怪v241Beta
 莱茵河水怪v241Beta
发布于 2015/07/23 18:36
字数 2419
阅读 473
收藏 20

1、GroovyWebApplicationContext 

在Spring 4.1之前没有提供Web集成的ApplicationContext,在《Spring4新特性——Groovy Bean定义DSL》中我们自己去实现的com.sishuok.spring4.context.support.WebGenricGroovyApplicationContext,而4.1其已经提供了相应实现,直接把《Spring4新特性——Groovy Bean定义DSL》配置中的相应类改掉即可。

 2、视图解析器标签

之前我们都是这样定义视图解析器:

Java代码 复制代码 收藏代码

  1. <bean id="mvcVelocityEngine" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">   

  2.     <property name="resourceLoaderPath" value="/WEB-INF/vm/,classpath:com/github/zhangkaitao" />   

  3. </bean>   

  4. <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">   

  5.     <property name="prefix" value=""/>   

  6.     <property name="suffix" value=".vm"/>   

  7.     <property name="cache" value="false"/>   

  8. </bean>  

    <bean id="mvcVelocityEngine" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/vm/,classpath:com/github/zhangkaitao" />
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        <property name="prefix" value=""/>
        <property name="suffix" value=".vm"/>
        <property name="cache" value="false"/>
    </bean>

而现在我们可以使用MVC标签定义: 

Java代码 复制代码 收藏代码

  1. <mvc:velocity-configurer resource-loader-path="/WEB-INF/vm/,classpath:com/github/zhangkaitao"/>   

  2. <mvc:view-resolvers>   

  3.     <mvc:velocity cache-views="false" prefix="" suffix=".vm"/>   

  4. </mvc:view-resolvers>  

    <mvc:velocity-configurer resource-loader-path="/WEB-INF/vm/,classpath:com/github/zhangkaitao"/>
    <mvc:view-resolvers>
        <mvc:velocity cache-views="false" prefix="" suffix=".vm"/>
    </mvc:view-resolvers>

 再来看一个更复杂的例子: 

Java代码 复制代码 收藏代码

  1. <mvc:velocity-configurer resource-loader-path="/WEB-INF/vm/,classpath:com/github/zhangkaitao"/>   

  2. <mvc:groovy-configurer resource-loader-path="classpath:templates/" cache-templates="false"/>   

  3. <mvc:view-resolvers>   

  4.     <mvc:content-negotiation>   

  5.         <mvc:default-views>   

  6.             <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">   

  7.                 <property name="jsonpParameterNames">   

  8.                     <set>   

  9.                         <value>jsonp</value>   

  10.                         <value>callback</value>   

  11.                     </set>   

  12.                 </property>   

  13.             </bean>   

  14.         </mvc:default-views>   

  15.     </mvc:content-negotiation>   

  16.     <mvc:velocity cache-views="false" prefix="" suffix=".vm"/>   

  17.     <mvc:groovy cache-views="false" suffix=".tpl"/>   

  18. </mvc:view-resolvers>  

    <mvc:velocity-configurer resource-loader-path="/WEB-INF/vm/,classpath:com/github/zhangkaitao"/>
    <mvc:groovy-configurer resource-loader-path="classpath:templates/" cache-templates="false"/>
    <mvc:view-resolvers>
        <mvc:content-negotiation>
            <mvc:default-views>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                    <property name="jsonpParameterNames">
                        <set>
                            <value>jsonp</value>
                            <value>callback</value>
                        </set>
                    </property>
                </bean>
            </mvc:default-views>
        </mvc:content-negotiation>
        <mvc:velocity cache-views="false" prefix="" suffix=".vm"/>
        <mvc:groovy cache-views="false" suffix=".tpl"/>
    </mvc:view-resolvers>

mvc:content-negotiation用于定义内容协商的视图解析器,且内部可以定义默认视图;然后我们又定义了mvc:velocity和mvc:groovy两个视图解析器;它们会按照顺序进行解析。另外几个视图解析器是:

 mvc:freemarker

mvc:bean-name

mvc:jsp

 这种方式有一个很大的问题就是只能做默认配置,如果想自定义其属性值就搞不定了,估计当时开发的人考虑不全或没有经验。

3、控制器标签

Spring 4.1提供了更丰富的控制器标签:

3.1、重定向视图控制器标签

Java代码 复制代码 收藏代码

  1. <mvc:redirect-view-controller   

  2.         path="/redirect"  

  3.         redirect-url="/status"  

  4.         context-relative="true"  

  5.         status-code="301"  

  6.         keep-query-params="true"/>  

    <mvc:redirect-view-controller
            path="/redirect"
            redirect-url="/status"
            context-relative="true"
            status-code="301"
            keep-query-params="true"/>

3.2、状态控制器标签

Java代码 复制代码 收藏代码

  1. <mvc:status-controller path="/status" status-code="200"/>  

    <mvc:status-controller path="/status" status-code="200"/>

3.3、带状态的视图控制器标签

Java代码 复制代码 收藏代码

  1. <mvc:view-controller path="/error/**" status-code="200"/>  

    <mvc:view-controller path="/error/**" status-code="200"/>

 4、Groovy Template引擎集成

Spring 4.1提供了对Groovy Template模板引擎的集成,其是一种DSL风格的模板引擎,其也是最早在Spring Boot中引入的。

4.1、Spring配置文件    

Java代码 复制代码 收藏代码

  1. <mvc:groovy-configurer resource-loader-path="classpath:templates/" cache-templates="false"/>   

  2. <mvc:view-resolvers>   

  3.     <mvc:groovy cache-views="false" suffix=".tpl"/>   

  4. </mvc:view-resolvers>  

    <mvc:groovy-configurer resource-loader-path="classpath:templates/" cache-templates="false"/>
    <mvc:view-resolvers>
        <mvc:groovy cache-views="false" suffix=".tpl"/>
    </mvc:view-resolvers>

4.2、模板heelo.tpl

Java代码 复制代码 收藏代码

  1. yieldUnescaped '<!DOCTYPE html>'  

  2. html {   

  3.   head {   

  4.     title('hello groovy templates')   

  5.   }   

  6.   body {   

  7.       div("hello $user.name")   

  8.   }   

  9. }  

yieldUnescaped '<!DOCTYPE html>'
html {
  head {
    title('hello groovy templates')
  }
  body {
      div("hello $user.name")
  }
}

具体语法请参考官方文档。

 5、 Jackson @JsonView支持 

可以使用@JsonView来分组渲染JSON数据,按需展示JSON数据。

5.1、模型

Java代码 复制代码 收藏代码

  1. public class User implements Serializable {   

  2.     public static interface OnlyIdView {}   

  3.     public static interface OnlyNameView {}   

  4.     public static interface AllView extends OnlyIdView, OnlyNameView {}   

  5.   

  6.     @JsonView(OnlyIdView.class)   

  7.     private Long id;   

  8.   

  9.     @JsonView(OnlyNameView.class)   

  10.     private String name;     

  11.     ……   

  12. }  

public class User implements Serializable {
    public static interface OnlyIdView {}
    public static interface OnlyNameView {}
    public static interface AllView extends OnlyIdView, OnlyNameView {}

    @JsonView(OnlyIdView.class)
    private Long id;

    @JsonView(OnlyNameView.class)
    private String name;  
    ……
}

定义了三个视图:OnlyIdView、OnlyNameView和AllView。

 5.2、控制器

Java代码 复制代码 收藏代码

  1. @RestController  

  2. public class JacksonJsonViewController {   

  3.   

  4.     @RequestMapping("/jackson1")   

  5.     @JsonView(User.OnlyIdView.class)   

  6.     public User test1() {   

  7.         return new User(1L, "zhangsan");   

  8.     }   

  9.   

  10.     @RequestMapping("/jackson2")   

  11.     @JsonView(User.OnlyNameView.class)   

  12.     public User test2() {   

  13.         return new User(1L, "zhangsan");   

  14.     }   

  15.   

  16.     @RequestMapping("/jackson3")   

  17.     @JsonView(User.AllView.class//可以省略   

  18.     public User test3() {   

  19.         return new User(1L, "zhangsan");   

  20.     }   

  21. }  

@RestController
public class JacksonJsonViewController {

    @RequestMapping("/jackson1")
    @JsonView(User.OnlyIdView.class)
    public User test1() {
        return new User(1L, "zhangsan");
    }

    @RequestMapping("/jackson2")
    @JsonView(User.OnlyNameView.class)
    public User test2() {
        return new User(1L, "zhangsan");
    }

    @RequestMapping("/jackson3")
    @JsonView(User.AllView.class) //可以省略
    public User test3() {
        return new User(1L, "zhangsan");
    }
}

使用@JsonView控制渲染哪些数据。

 6、Jsonp支持  

6.1、MappingJackson2JsonView提供的支持 

Java代码 复制代码 收藏代码

  1. <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">   

  2.     <property name="jsonpParameterNames">   

  3.         <set>   

  4.             <value>jsonp</value>   

  5.             <value>callback</value>   

  6.         </set>   

  7.    </property>   

  8. </bean>  

    <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
        <property name="jsonpParameterNames">
            <set>
                <value>jsonp</value>
                <value>callback</value>
            </set>
       </property>
    </bean>

然后访问如http://localhost:8080/json?callback=callback即可得到JSONP响应:callback({"user":{"id":1,"name":"zhangsan"}});。

 6.2、对使用HttpMessageConverter的@ResponseBody的支持 

Java代码 复制代码 收藏代码

  1. @Order(2)   

  2. @ControllerAdvice(basePackages = "com.github")   

  3. public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {   

  4.     public JsonpAdvice() {   

  5.         super("callback""jsonp"); //指定jsonpParameterNames   

  6.     }   

  7. }  

@Order(2)
@ControllerAdvice(basePackages = "com.github")
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    public JsonpAdvice() {
        super("callback", "jsonp"); //指定jsonpParameterNames
    }
}

访问http://localhost:8080/jackson1?callback=callback即可看到JSONP响应。 

 

@ContollerAdvice的作用请参考《Spring3.2新注解@ControllerAdvice》,basePackages用于指定对哪些包里的Controller起作用。

 6.3、ResponseBodyAdvice

我们之前实现的JsonpAdvice其继承自AbstractJsonpResponseBodyAdvice,而AbstractJsonpResponseBodyAdvice继承自ResponseBodyAdvice,其作用是在响应体写出之前做一些处理: 

Java代码 复制代码 收藏代码

  1. @Order(1)   

  2. @ControllerAdvice(basePackages = "com.github")   

  3. public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {   

  4.   

  5.     @Override  

  6.     public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {   

  7.         return methodParameter.getMethod().getReturnType().isAssignableFrom(User.class);   

  8.     }   

  9.   

  10.     @Override  

  11.     public Object beforeBodyWrite(   

  12.             Object obj, MethodParameter methodParameter, MediaType mediaType,   

  13.             Class<? extends HttpMessageConverter<?>> converterType,   

  14.             ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {   

  15.   

  16.         User user = ((User)obj);   

  17.         user.setName("---" + user.getName() + "---");   

  18.         return user;   

  19.     }   

  20. }  

@Order(1)
@ControllerAdvice(basePackages = "com.github")
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        return methodParameter.getMethod().getReturnType().isAssignableFrom(User.class);
    }

    @Override
    public Object beforeBodyWrite(
            Object obj, MethodParameter methodParameter, MediaType mediaType,
            Class<? extends HttpMessageConverter<?>> converterType,
            ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        User user = ((User)obj);
        user.setName("---" + user.getName() + "---");
        return user;
    }
}

1、supports指定支持哪些类型的方法进行处理,此处是返回值为User的;2、我们得到User对象然后在名字前后拼上”---“ ;3、可以指定多个ResponseBodyAdvice,使用@Order指定顺序。访问http://localhost:8080/jackson2?callback=callback可以看到效果。

 7、Gson HttpMessageConverter

7.1、Spring配置 

Java代码 复制代码 收藏代码

  1. <mvc:annotation-driven>   

  2.     <mvc:message-converters>   

  3.         <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"/>   

  4.     </mvc:message-converters>   

  5. </mvc:annotation-driven>  

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

使用方式和Jackson Json类似。本文使用的是<gson.version>2.2.4</gson.version>版本。

8、Protobuf HttpMessageConverter

8.1、Spring配置 

Java代码 复制代码 收藏代码

  1. <mvc:annotation-driven>   

  2.     <mvc:message-converters>   

  3.         <bean class="org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter">   

  4.             <constructor-arg>   

  5.                 <bean class="com.github.zhangkaitao.web.controller.MyExtensionRegistryInitializer"/>   

  6.             </constructor-arg>   

  7.         </bean>   

  8.     </mvc:message-converters>   

  9. </mvc:annotation-driven>  

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter">
                <constructor-arg>
                    <bean class="com.github.zhangkaitao.web.controller.MyExtensionRegistryInitializer"/>
                </constructor-arg>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

 8.2、定义protobuf message(proto/user.proto)

Java代码 复制代码 收藏代码

  1. package com.github.zhangkaitao.pb;   

  2.     

  3.  option java_package = "com.github.zhangkaitao.pb";   

  4.  option java_outer_classname = "UserProtos";   

  5.     

  6.  message User {   

  7.    optional int64 id = 1;   

  8.    optional string name = 2;   

  9.  }  

package com.github.zhangkaitao.pb;
 
 option java_package = "com.github.zhangkaitao.pb";
 option java_outer_classname = "UserProtos";
 
 message User {
   optional int64 id = 1;
   optional string name = 2;
 }

 8.3、添加maven插件自动把protobuf message转化成Java代码

Java代码 复制代码 收藏代码

  1. <plugin>   

  2.     <groupId>com.google.protobuf.tools</groupId>   

  3.     <artifactId>maven-protoc-plugin</artifactId>   

  4.     <version>0.1.10</version>   

  5.     <executions>   

  6.         <execution>   

  7.             <id>generate-sources</id>   

  8.             <goals>   

  9.                 <goal>compile</goal>   

  10.             </goals>   

  11.             <phase>generate-sources</phase>   

  12.             <configuration>   

  13.                 <protoSourceRoot>${basedir}/src/main/proto/</protoSourceRoot>   

  14.                 <includes>   

  15.                     <param>**/*.proto</param>   

  16.                 </includes>   

  17.             </configuration>   

  18.         </execution>   

  19.     </executions>   

  20.     <configuration>   

  21.         <protocExecutable>D:/software/protoc.exe</protocExecutable>   

  22.     </configuration>   

  23. </plugin>  

            <plugin>
                <groupId>com.google.protobuf.tools</groupId>
                <artifactId>maven-protoc-plugin</artifactId>
                <version>0.1.10</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <phase>generate-sources</phase>
                        <configuration>
                            <protoSourceRoot>${basedir}/src/main/proto/</protoSourceRoot>
                            <includes>
                                <param>**/*.proto</param>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <protocExecutable>D:/software/protoc.exe</protocExecutable>
                </configuration>
            </plugin>

 8.4、测试控制器 

Java代码 复制代码 收藏代码

  1. @RestController  

  2. public class ProtobufController {   

  3.     @RequestMapping("/proto/read")   

  4.     public ResponseEntity<UserProtos.User> protoRead() {   

  5.         return ResponseEntity.ok(UserProtos.User.newBuilder().setId(1).setName("zhangsan").build());   

  6.     }   

  7.     @RequestMapping("/proto/write")   

  8.     public ResponseEntity<UserProtos.User> protoRead(RequestEntity<UserProtos.User> requestEntity) {   

  9.         System.out.println("server===\n" + requestEntity.getBody());   

  10.         return ResponseEntity.ok(requestEntity.getBody());   

  11.     }   

  12. }  

@RestController
public class ProtobufController {
    @RequestMapping("/proto/read")
    public ResponseEntity<UserProtos.User> protoRead() {
        return ResponseEntity.ok(UserProtos.User.newBuilder().setId(1).setName("zhangsan").build());
    }
    @RequestMapping("/proto/write")
    public ResponseEntity<UserProtos.User> protoRead(RequestEntity<UserProtos.User> requestEntity) {
        System.out.println("server===\n" + requestEntity.getBody());
        return ResponseEntity.ok(requestEntity.getBody());
    }
}

 8.5、测试用例(com.github.zhangkaitao.proto.ProtoTest)   

Java代码 复制代码 收藏代码

  1. @Test  

  2. public void testRead() {   

  3.     HttpHeaders headers = new HttpHeaders();   

  4.     RequestEntity<UserProtos.User> requestEntity =   

  5.             new RequestEntity<UserProtos.User>(headers, HttpMethod.POST, URI.create(baseUri + "/proto/read"));   

  6.   

  7.     ResponseEntity<UserProtos.User> responseEntity =   

  8.             restTemplate.exchange(requestEntity, UserProtos.User.class);   

  9.   

  10.     System.out.println(responseEntity.getBody());   

  11. }   

  12.   

  13. @Test  

  14. public void testWrite() {   

  15.     UserProtos.User user = UserProtos.User.newBuilder().setId(1).setName("zhangsan").build();   

  16.     HttpHeaders headers = new HttpHeaders();   

  17.     RequestEntity<UserProtos.User> requestEntity =   

  18.             new RequestEntity<UserProtos.User>(user, headers, HttpMethod.POST, URI.create(baseUri + "/proto/write"));   

  19.   

  20.     ResponseEntity<UserProtos.User> responseEntity =   

  21.             restTemplate.exchange(requestEntity, UserProtos.User.class);   

  22.     System.out.println(responseEntity.getBody());   

  23. }  

    @Test
    public void testRead() {
        HttpHeaders headers = new HttpHeaders();
        RequestEntity<UserProtos.User> requestEntity =
                new RequestEntity<UserProtos.User>(headers, HttpMethod.POST, URI.create(baseUri + "/proto/read"));

        ResponseEntity<UserProtos.User> responseEntity =
                restTemplate.exchange(requestEntity, UserProtos.User.class);

        System.out.println(responseEntity.getBody());
    }

    @Test
    public void testWrite() {
        UserProtos.User user = UserProtos.User.newBuilder().setId(1).setName("zhangsan").build();
        HttpHeaders headers = new HttpHeaders();
        RequestEntity<UserProtos.User> requestEntity =
                new RequestEntity<UserProtos.User>(user, headers, HttpMethod.POST, URI.create(baseUri + "/proto/write"));

        ResponseEntity<UserProtos.User> responseEntity =
                restTemplate.exchange(requestEntity, UserProtos.User.class);
        System.out.println(responseEntity.getBody());
    }

测试用例知识请参考《Spring MVC测试框架详解——服务端测试》和《Spring MVC测试框架详解——客户端测试》。

测试过程中会抛出:

Java代码 复制代码 收藏代码

  1. Caused by: java.lang.UnsupportedOperationException   

  2.     at java.util.Collections$UnmodifiableMap.put(Collections.java:1342)   

  3.     at org.springframework.http.HttpHeaders.set(HttpHeaders.java:869)   

  4.     at org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter.setProtoHeader(ProtobufHttpMessageConverter.java:196)  

Caused by: java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableMap.put(Collections.java:1342)
	at org.springframework.http.HttpHeaders.set(HttpHeaders.java:869)
	at org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter.setProtoHeader(ProtobufHttpMessageConverter.java:196)

这是因为ProtobufHttpMessageConverter会修改响应头,但是ResponseEntity构造时HttpHeaders是不允许修改的。暂时解决办法是注释掉:

Java代码 复制代码 收藏代码

  1. //setProtoHeader(outputMessage, message);  

//setProtoHeader(outputMessage, message);

9、RequestEntity/ResponseEntity

Spring 4.1提供了ResponseEntity配对的RequestEntity,使用方式和HttpEntity一样。具体可以参考com.github.zhangkaitao.web.controller.RequestResponseEntityController。

 10、MvcUriComponentsBuilder

其作用可以参考《Spring4新特性——注解、脚本、任务、MVC等其他特性改进》,Spring 4.1又提供了一个新的方法MvcUriComponentsBuilder.fromMappingName用于根据控制器方法来生成请求URI。

 Java代码 复制代码 收藏代码

  1. @RestController  

  2. public class MvcUriComponentsBuilderController {   

  3.   

  4.     @RequestMapping("/uri")   

  5.     public String mvcUriComponentsBuilder1() {   

  6.         return MvcUriComponentsBuilder.fromMappingName("MUCBC#mvcUriComponentsBuilder1").build();   

  7.     }   

  8.     @RequestMapping("/uri/{id}")   

  9.     public String mvcUriComponentsBuilder2(@PathVariable Long id) {   

  10.         return MvcUriComponentsBuilder.fromMappingName("MUCBC#mvcUriComponentsBuilder2").arg(0"123").build();   

  11.     }   

  12. }  

@RestController
public class MvcUriComponentsBuilderController {

    @RequestMapping("/uri")
    public String mvcUriComponentsBuilder1() {
        return MvcUriComponentsBuilder.fromMappingName("MUCBC#mvcUriComponentsBuilder1").build();
    }
    @RequestMapping("/uri/{id}")
    public String mvcUriComponentsBuilder2(@PathVariable Long id) {
        return MvcUriComponentsBuilder.fromMappingName("MUCBC#mvcUriComponentsBuilder2").arg(0, "123").build();
    }
}

规则是“控制器所有大写字母#方法名”找到相应的方法。 另外可以直接在页面中使用如下方式获取相应的URI:

Java代码 复制代码 收藏代码

  1. ${s:mvcUrl('MUCBC#mvcUriComponentsBuilder2').arg(0,"123").build()}  

${s:mvcUrl('MUCBC#mvcUriComponentsBuilder2').arg(0,"123").build()}

如上方式只能在正常EL 3.0的容器中运行,可参考《Expression Language 3.0新特性》。 

11、MockRestServiceServer

MockRestServiceServer目前提供了对AsyncRestTemplate的支持,使用方式和RestTemplate一样。可参考《Spring MVC测试框架详解——客户端测试》。

 12、MockMvcConfigurer

Spring 4.1提供了MockMvcConfigurer用于进行一些通用配置,使用方式如下:

Java代码 复制代码 收藏代码

  1. mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(defaultSetup()).build();   

mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(defaultSetup()).build();

MockMvcConfigurer实现: 

Java代码 复制代码 收藏代码

  1. private MockMvcConfigurer defaultSetup() {   

  2.     return new MockMvcConfigurer() {   

  3.         @Override  

  4.         public void afterConfigurerAdded(ConfigurableMockMvcBuilder<?> configurableMockMvcBuilder) {   

  5.             configurableMockMvcBuilder.alwaysExpect(status().isOk());   

  6.         }   

  7.         @Override  

  8.         public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> configurableMockMvcBuilder, WebApplicationContext webApplicationContext) {   

  9.             return new RequestPostProcessor() {   

  10.                 @Override  

  11.                 public MockHttpServletRequest postProcessRequest(MockHttpServletRequest mockHttpServletRequest) {   

  12.                     mockHttpServletRequest.setAttribute("aa""aa");   

  13.                     return mockHttpServletRequest;   

  14.                 }   

  15.             };   

  16.         }   

  17.     };   

  18. }  

    private MockMvcConfigurer defaultSetup() {
        return new MockMvcConfigurer() {
            @Override
            public void afterConfigurerAdded(ConfigurableMockMvcBuilder<?> configurableMockMvcBuilder) {
                configurableMockMvcBuilder.alwaysExpect(status().isOk());
            }
            @Override
            public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> configurableMockMvcBuilder, WebApplicationContext webApplicationContext) {
                return new RequestPostProcessor() {
                    @Override
                    public MockHttpServletRequest postProcessRequest(MockHttpServletRequest mockHttpServletRequest) {
                        mockHttpServletRequest.setAttribute("aa", "aa");
                        return mockHttpServletRequest;
                    }
                };
            }
        };
    }

可以在如上实现中进行一些通用配置,如安全(往Request中扔安全对象之类的)。测试用例可参考com.github.zhangkaitao.proto.ProtoTest2。

本文转载自:

共有 人打赏支持
莱茵河水怪v241Beta
粉丝 1
博文 25
码字总数 7887
作品 0
深圳
程序员
私信 提问
Spring4新特性——Web开发的增强

Spring4新特性——泛型限定式依赖注入 Spring4新特性——核心容器的其他改进 Spring4新特性——Web开发的增强 Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC Spring4新特性...

张升强
2014/04/02
0
0
5分钟构建spring web mvc REST风格HelloWorld

当然写本文的目的不是为了速度,只是表明现在构建一个Spring web mvc Rest风格的HelloWorld应用会很简单。不过如果看过Spring Boot这个项目,可能只需要最多3分钟就能构建一个简单的Rest风格...

黄金小猪2号
2014/01/07
4.1K
2
Spring4新特性——泛型限定式依赖注入

Spring4新特性——泛型限定式依赖注入 Spring4新特性——核心容器的其他改进 Spring4新特性——Web开发的增强 Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC Spring4新特性...

Big_BoBo
2013/12/26
0
0
spring web 4.1处理json

Spring mvc处理json,我们都知道使用@ResponseBody,处理xml也是用此注解。如果想spring mvc的使用@ResponseBody注解处理json,我们需要加入一些处理bean,也可以使用默认spring提供的。 通过...

引鸩怼孑
2015/07/09
0
0
spring2.0-2.5-3.0变化

忽然间想知道spring2.0到2.5 再到3.0的变化,就到网上搜索一下。方便查看而已 2.5的新特性 Spring2.5rc1发布了,一直想知道它葫芦里卖什么药,以下是文档里的change.log 1. JDK版本: JDK至...

dengzhangtao
2010/12/06
0
1

没有更多内容

加载失败,请刷新页面

加载更多

验证码

response生成验证码 验证码的作用:防止恶意注册、攻击等 网站上看到的验证码,实际上都是一些图片,而这些图片都是程序(Servlet)生成的! package day19.test; import java.awt.Color; i...

码农屌丝
42分钟前
0
0
day147-2018-11-14-英语流利阅读-待学习

《毒液》刚刚上映,创造漫威宇宙的人却走了 雪梨 2018-11-14 1.今日导读 中国的金庸创造了侠义英雄和江湖传奇,而大洋彼岸的斯坦·李也同样创造了一个绚烂璀璨的漫威宇宙,他构思的每个超级英...

飞鱼说编程
44分钟前
3
0
CentOS 安装PHP5和PHP7

安装PHP5 下载解压二进制包 [root@test-a src]# cd /usr/local/src/[root@test-a src]# wget http://cn2.php.net/distributions/php-5.6.32.tar.bz2[root@test-a src]# tar jxvf php-5.6......

野雪球
今天
4
0
修改jfinal默认的redis序列化方式

jfinal 越来越流行, jfinal的redis插件默认的序列化方式是fst。 但是系统中其他项目中用的是spring data redis中的StringRedisTemplate,所有的value都是通过gson转化成String放进去的。 直接...

采蘑菇的大叔
今天
1
2
windows上类似dnsmasq的软件Dual DHCP DNS Server

官网地址:http://dhcp-dns-server.sourceforge.net/官网定向的下载地址:https://sourceforge.net/projects/dhcp-dns-server/files/ 设置参考地址:http://blog.51cto.com/zhukeqiang/18264......

xueyuse0012
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部