由于Spring 4.1的Java 8的的java.util.Optional ,容器对象可能会或可能不包含非空值,支持与@RequestParam , @RequestHeader和@MatrixVariable 。 使用Java 8的java.util.Optional请确保参数永远不会为null 。 
请求参数
 在此示例中,我们将使用@RequestParam将java.time.LocalDate绑定为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之前,我们会遇到一个例外,即找不到匹配的编辑器或转换策略。 从Spring 4.1开始,这不再是问题。 为了验证绑定是否正常工作,我们可以创建一个简单的集成测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class SampleSomeControllerTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic 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: "));
}两个测试都应该是绿色的!
请求标题
 同样,我们可以将@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: "));
}矩阵变量
 在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();
} 可以通过/o/m/42;p=4;q=2 url调用上述方法。 让我们为此做一个测试: 
@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属性设置为false 。 默认情况下,它设置为true 。 我已经用WebMvcConfigurerAdapter完成了,如下所示: 
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {UrlPathHelper urlPathHelper = new UrlPathHelper();urlPathHelper.setRemoveSemicolonContent(false);configurer.setUrlPathHelper(urlPathHelper);}
}现在所有测试都通过了! 请在这里找到本文的源代码: https : //github.com/kolorobot/spring41-samples
翻译自: https://www.javacodegeeks.com/2014/07/spring-4-1-and-java-8-java-util-optional.html