This is the parameter of the request pass
This is the background received parameter,The id in the child attribute was incorrectly assigned to the main attribute,Of course, there is also a parameter passing problem. The type in constructionBasisList should be passed to String, but was incorrectly passed to List
There is a processing done to prevent xss
jackson V2.11.4
spring-boot V2.7.10
Comment From: wilkinsona
Thanks for the report, but Spring Boot 2.7.x is no longer supported. This also appears to be a problem with Jackson which, other than its initial configuration, is out of Spring Boot's control.
If you can reproduce the problem with a supported version of Spring Boot (3.2 or later) and provide a minimal sample that demonstrates that Spring Boot is causing the problem, we can re-open the issue and take another look.
Comment From: FQXCS
I upgraded the version to: spring-boot V3.2.9、jackson V2.15.4. And I forced jackson to version 2.17.2. Both the default version and the latest jackson version still have problems.
This is a minimal sample:
@Slf4j
public class JacksonXssClean extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) {
try {
return p.getValueAsString();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
@RequiredArgsConstructor
@Configuration
public class EfpxXssAutoConfiguration implements WebMvcConfigurer {
@Bean
public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer() {
return builder -> builder.deserializerByType(String.class, new JacksonXssClean());
}
}
@Data
public class MasterVo {
private String id;
private String masterName;
private List<SlaveVo> slaveVoList;
}
@Data
public class SlaveVo {
private String id;
private String name;
private String type;
private String typeStr;
}
@RestController
@RequiredArgsConstructor
@RequestMapping("/test")
public class TestController {
@PostMapping("/test01")
public String temporaryStorage(@RequestBody MasterVo vo) {
return "";
}
}
This is the request parameter:
{
"id": "8d4c1e7ab5184705a056389a755c4bce",
"masterName": "test",
"slaveVoList": [
{
"name": "slaveVoList01",
"type": [
"01"
],
"typeStr": "type01",
"id": "66ce1086d562476a8331a6065ed5bb50"
},
{
"businessId": "8d4c1e7ab5184705a056389a755c4bce",
"name": "slaveVoList02",
"type": [
"01"
],
"typeStr": "type01",
"id": "6a98ff39a92c4b6a93a3cb93614e5810"
}
]
}
com.fasterxml.jackson.databind.deser.BeanDeserializer#deserializeFromObject I found out after tracing the code that I assigned type to slaveVoList during the recursive assignment process that somehow popped out, causing slavevolist.id to be assigned to MasterVo.id
Comment From: philwebb
@FQXCS Could we please have the sample as a complete project that we can download and run. We'd also prefer if Lombok wasn't involved.
Comment From: FQXCS
I'm sorry that I can't give you the original project. This project was built by me temporarily, and there is also this problem. springboot3.zip
Comment From: bclozel
I had a look to your sample and there are several issues.
First, your custom configuration class extends WebMvcConfigurer, which completely disables Spring Boot's web auto-configuration. You should remove the extend WebMvcConfigurer part to get a better experience.
Second, I believe the JSON input you have provided is invalid as the "type" attribute is given as an array, whereas the Java objects expect a single String. Removing your custom deserializer yields Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of typejava.lang.Stringfrom Array value (tokenJsonToken.START_ARRAY)].
Once I have removed your custom deserializer and fixed the request JSON document, I can log the payload received in the controller:
c.e.s.test.controller.TestController : MasterVo{id='8d4c1e7ab5184705a056389a755c4bce', masterName='test', slaveVoList=[SlaveVo{id='66ce1086d562476a8331a6065ed5bb50', name='slaveVoList01', type='01', typeStr='type01'}, SlaveVo{id='6a98ff39a92c4b6a93a3cb93614e5810', name='slaveVoList02', type='01', typeStr='type01'}]}
I believe the problem comes from your custom Jackson deserializer; please ask this question on StackOverflow.
Comment From: FQXCS
Thank you for your answer. I find that the type of "type" is wrong, but I debug that JacksonXssClean returns null value. Because there's a try catch, even if the "type" parsing fails, the value is returned as null and the correct value is assigned (MasterVo.slavevList[n].type = null), rather than "MasterVo.slavevList[0].id" incorrectly assigned to "MasterVo.id".