SandhyaRani D
SandhyaRani D

Reputation: 77

@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!

Upvotes: 0

Views: 5438

Answers (3)

obada halak
obada halak

Reputation: 1

You can simply set false value in required params

@GetMapping(value = "/jobs")
public BaseResponse<Object>jobs(
        @RequestParam JobStatus jobStatus,
        @RequestParam int page,
        @RequestParam String query,
        @RequestParam(required = false) Boolean online,
        @RequestParam(required = false) Boolean isPaid
){
 

}

Upvotes: 0

SandhyaRani D
SandhyaRani D

Reputation: 77

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.

Upvotes: 0

dev2d
dev2d

Reputation: 4262

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();                                                           
} 

Upvotes: 1

Related Questions