Will May opened SPR-12312 and commented
Add support for being able to validate a list of objects similar to the example below, where Foo is a class which has various JSR 303 annotations on its fields:
@RequestMapping(value = "/foo", method = RequestMethod.POST)
public void insertFoos(@Valid @RequestBody List<Foo> foos) {
...
}
I've managed to partially implement the functionality by extending the LocalValidatorFactoryBean
and setting the nested path to the current list path ([i]
) while calling super.validate
in a loop. This almost works apart from the fact that the BeanWrapper
cannot retrieve an invalid value if one fails validation and so throws an exception while trying to throw an exception.
So, in summary, the BeanWrapper needs to be able to work directly on lists rather than only being able to work on objects containing lists.
Affects: 4.0.7
Issue Links:
- #18007 @Validated
support on Iterables (and implementors)
- #19182 Validate values in top-level Map parameters
1 votes, 4 watchers
Comment From: spring-projects-issues
Will May commented
It's possible that this might be a duplicate or a subtask of #6751 but that appears to be more to do with Map
of objects rather than Collection
of objects.
Comment From: spring-projects-issues
Frédéric Camblor commented
+1 on this (just created a duplicate of the issue before finding this one -> #18007)
Comment From: spring-projects-issues
mathsworld2001 commented
I recently came across this very same issue. Some at stackoverflow claims that this should already work as expected. I still cannot make this work. Can anyone confirm the current status of this ticket?
Comment From: spring-projects-issues
Will May commented
Still doesn't work. See an example at https://github.com/wjam/spr-12312
Comment From: SumithraPrasad
@Validated
with MockMVC is not working.
@RunWith(MockitoJUnitRunner.class)
@Slf4j
public class TestController {
private MockMvc mvc;
@Mock
private TestService service;
@InjectMocks
private Controller controller;
private ObjectMapper mapper = new ObjectMapper();
@Before
public void setup() { // MockMvc standalone approach mvc =
mvc = MockMvcBuilders.standaloneSetup(controller).setValidator(validator()).setControllerAdvice(new InvoiceServiceExceptionHandler())
.build();
}
@Test
public void whenNullValue_thenReturns400() throws JsonProcessingException, Exception {
TestDTO testDTO = new TestDTO();
testDTO.setId(null);
ArrayList<TestDTO> testList = new ArrayList<TestDTO>(Arrays.asList(testDTO));
String jsonTestList = mapper.writeValueAsString(testList);
MvcResult responseMVC = mvc.perform(post("/v1/test").content(jsonTestList).header(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest()).andReturn();
}
Comment From: rstoyanchev
@SumithraPrasad, I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference. In particular avoid use of unquoted @
which are mentions on Github.
Also if it isn't supported to begin with, then it can't work with MockMvc.
Comment From: exe-atewinkel
This is a very old issue, but I've just run into this problem. I want to validate a Collection of objects, using validation groups.
Putting @Validated({Default.class, MyValidationGroup.class})
before the collection does not trigger validation of MyValidationGroup
. Apparently it should be before the type parameter of the collection (similar to @Valid
, which does not support groups), but unlike @Valid
, @Validated
cannot be applied to a type parameter.
This makes validating a collection of objects with specific validation groups impossible. I would greatly appreciate it if something could be done to fix this.
Specifying groups for an array of objects also does not work.
Comment From: rstoyanchev
The main challenge for bean validation support on a collection of objects is representing the results. You need one BindingResult
for each object being validated, while SpringValidatorAdapter
is only prepared to validate one object and prepare one BindingResult
.
As part of changes to add built-in web support for method validation (see #30645) for 6.1, we already support applying method validation and preparing a MethodValidationResult
with separate results for each parameter. This also supports representing results from the validation of Lists and Maps of objects.
So this should already work (with the latest 6.1 milestone 4) when method validation is applied via AOP (i.e. with @Validated
at the class level). For the built-in method validation however in spring-web, I expect we need to adjust the logic that decides whether to apply method validation or to validate the parameter individually as we have always done. I'm going to schedule this to experiment for RC1.
@exe-atewinkel, thanks for the additional comment. As part of the work, I'll also experiment with applying groups, and will comment further on that.
Comment From: rstoyanchev
The built-in method validation in Spring MVC and WebFlux now works for List validation with some minor changes b068742ec8803334d4d2a91484aadf60c1e8ef4f as part of the more extensive changes for #30645.