简体   繁体   中英

@RequestParam with Optional Spring REST

I have a Spring REST endpoint with Optional request params like below:

public ResponseEntity<Product> globalProduct(@RequestParam Optional<Integer> id, @RequestParam Optional<String> name){

return ResponseEntity.ok(tm));
}

when I'm trying to test this endpoint which uses Mockito framework

@Test                                                                               
public void testGlobalProduct() throws Exception {                        
    URI uri = UriComponentsBuilder.fromPath("/api/products")                  
            .queryParam("id", Optional.of(1)                                               
            .queryParam("name", Optional.empty())                                 
            .build().toUri();                                                       
    mockMvc.perform( MockMvcRequestBuilders.get(uri)                                
            .accept(MediaType.APPLICATION_JSON))                                    
            .andExpect(status().isOk())                                             
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))           
            .andDo(MockMvcResultHandlers.print())                                   
            .andReturn();                                                           
} 

So the queryParams id and name should be Optional.of(1) and Optional.empty(), but when I debug in the rest api implementaion I see id and name has been wrapped with values Optional[Optional[1]] and Optiona[Optional.empty]] .

I know I can use @RequestParams(required=false) but I dont want to use that way in this context.

How do we unwrap Optional[Optional[1]] Optiona[Optional.empty]] Is this correct? Any suggestions please?

Thanks in Advance!

That is because you are passing an Optional in the query param which is again wrapped in an optional at controller layer. Try following and check.

@Test                                                                               
public void testGlobalProduct() throws Exception {                        
    URI uri = UriComponentsBuilder.fromPath("/api/products")                  
            .queryParam("id", 1)                                                                               
            .build().toUri();                                                       
    mockMvc.perform( MockMvcRequestBuilders.get(uri)                                
            .accept(MediaType.APPLICATION_JSON))                                    
            .andExpect(status().isOk())                                             
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))           
            .andDo(MockMvcResultHandlers.print())                                   
            .andReturn();                                                           
} 

It's working. I put default value for param 'name'

public ResponseEntity<Product> globalProduct(@RequestParam Optional<Integer> id,  @RequestParam(value = "") Optional<String> name){

        return ResponseEntity.ok(tm));
   }

And I did not pass any requestParam from the test, so it defaults to empty. It works.

@Test                                                                               
public void testGlobalProduct() throws Exception {                        
    URI uri = UriComponentsBuilder.fromPath("/api/products")                  
            .queryParam("id", Optional.of(1)                                               
            .build().toUri();                                                       
    mockMvc.perform( MockMvcRequestBuilders.get(uri)                                
            .accept(MediaType.APPLICATION_JSON))                                    
            .andExpect(status().isOk())                                             
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))           
            .andDo(MockMvcResultHandlers.print())                                   
            .andReturn();                                                           
} 

Thanks all for suggestions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM