Spring 4.1与Java 8 java.util.Optional

java admin 85700 0 评论

在Spring 4.1中,利用Java 8的java.util.Optional,通过@RequestParam@RequestHeader@MatrixVariable三个注解,支持了仅包含非空(non-null)的容器对象。有了Java 8的java.util.Optional,你可以保证你的参数永远不会为null

Request Params (请求参数)

在这个例子中,我们将使用@RequestParam注解把java.time.LocalData绑定为java.util.Optional

 @RestController @RequestMapping("o") public class SampleController {
@RequestMapping(value = "r", produces = "text/plain")

 public String requestParamAsOptional(

 @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)

 @RequestParam(value = "ld") Optional<LocalDate> localDate) {
StringBuilder result = new StringBuilder("ld: ");
localDate.ifPresent(value -> result.append(value.toString()));
return result.toString();

 } } 

在Spring 4.1之前,可能会发生no matching editors or coversion strategy was found(找不到匹配的编辑或转换策略)异常,这在Spring 4.1中不再是一个问题。为了验证这个绑定能够有效的运行,我们编写了一个简单的集成测试:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class SampleSomeControllerTest {
@Autowired

 private WebApplicationContext wac;

 private MockMvc mockMvc;
@Before

 public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();

 }

 // ... } 

在这第一个测试中,我们将检测是否这个绑定有效的运行并且返回有效的结果:

 @Test public void bindsNonNullLocalDateAsRequestParam() throws Exception {

 mockMvc.perform(get("/o/r").param("ld", "2020-01-01"))

 .andExpect(content().string("ld: 2020-01-01")); } 

在接下来的测试中,我们将不会传入ld参数:

 @Test public void bindsNoLocalDateAsRequestParam() throws Exception {

 mockMvc.perform(get("/o/r"))

 .andExpect(content().string("ld: ")); } 

两个测试都顺利通过了!

Request Header (请求头部)

类似的,我们可以把@RequestHeader绑定到java.util.Optional

 @RequestMapping(value = "h", produces = "text/plain") public String requestHeaderAsOptional(
@RequestHeader(value = "Custom-Header") Optional<String> header) {
StringBuilder result = new StringBuilder("Custom-Header: ");

 header.ifPresent(value -> result.append(value));
return result.toString(); } 

然后测试:

 @Test public void bindsNonNullCustomHeader() throws Exception {

 mockMvc.perform(get("/o/h").header("Custom-Header", "Value"))

 .andExpect(content().string("Custom-Header: Value")); }
@Test public void noCustomHeaderGiven() throws Exception {

 mockMvc.perform(get("/o/h").header("Custom-Header", ""))

 .andExpect(content().string("Custom-Header: ")); } 

Matrix Variables (数组变量)

在Spring 3.2中引入的@MatrixVariable注解表明了在一个路径段中的方法参数应该被绑定到一个名值对中:

 @RequestMapping(value = "m/{id}", produces = "text/plain") public String execute(@PathVariable Integer id,


 @MatrixVariable Optional<Integer> p,


 @MatrixVariable Optional<Integer> q) {
StringBuilder result = new StringBuilder();

 result.append("p: ");

 p.ifPresent(value -> result.append(value));

 result.append(", q: ");

 q.ifPresent(value -> result.append(value));
return result.toString(); } 

以上的方法可以通过获取url/o/m/42;p=4;q=2来调用。我们写个例子测试一下:

 @Test public void bindsNonNullMatrixVariables() throws Exception {

 mockMvc.perform(get("/o/m/42;p=4;q=2"))

 .andExpect(content().string("p: 4, q: 2")); } 

不幸的是,这个测试失败了。因为在Spring MVC中,@MatrixVariable注解默认是禁止的。为了使它能用,我们需要调整RequestMappingHandlerMapping的属性removeSemicolonContent,默认为true,设置为false。通过WebMvcConfigurerAdapter设置了这个属性,就像下面这样:

 @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter {

 @Override

 public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);

 } } 

现在,所有的测试都可以通过了。在这里你可以找到这篇文章的示例源码(github)。

原文链接: javacodegeeks 翻译: ImportNew.com - xiafei
译文链接: http://www.importnew.com/13169.html
[ 转载请保留原文出处、译者和译文链接。]

关于作者: xiafei

又一个程序员即将诞生。 关注C++/Java语言,web开发学习中。(新浪微博:@dutxiaop

查看xiafei的更多文章 >>

转载请注明: 飞嗨_分享互联网 » Spring 4.1与Java 8 java.util.Optional

赞 (0) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽

高效,专业,符合SEO

联系我们