环境:
Spring启动:2.0.5.RELEASE
问题:
给定:
@Transactional(readOnly = true)
@GetMapping(value = "/list")
public ResponseEntity<List<CarDTO>> getList(@RequestParam final InteriorDTO interior) {
return ResponseEntity.ok(getCarsBy(interior));
}
DTO
public class InteriorDTO extends DetailsDTO {
}
public class DetailsDTO {
private int listSize;
}
时间:
GET/cars/list?interior=eyJsaXN0U2l6ZSI6NX0=
(eyJsaXN0U2l6ZSI6NX0=
采用 base64 编码:{"listSize":5}
)
然后:
Failed to convert value of type 'java.lang.String' to required type '(...).InteriorDTO'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type '(...).InteriorDTO': no matching editors or conversion strategy found
问题:
如何为 jackson 正确定义解串器以使他处理这种情况?应该是类似this的东西吗? (对我不起作用)?
最佳答案
您必须创建自定义 Spring 转换器:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class Base64InteriorToDtoConverter implements Converter<String, InteriorDTO> {
@Override
public InteriorDTO convert(String source) {
ObjectMapper objectMapper = new ObjectMapper();
byte[] valueDecoded = Base64.decodeBase64(source);
InteriorDTO interiorDTO = null;
try {
interiorDTO = objectMapper.readValue(new String(valueDecoded), InteriorDTO.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return interiorDTO;
}
}
(只需记住正确的异常处理)
对于 Base64 解码,我使用了 Apache Commons Codec 库,即我的 build.gradle
文件:
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'commons-codec:commons-codec:1.13'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
Jackson 用于将 String 值映射到对象。请记住 DetailsDTO 类中的 setter:
public class DetailsDTO {
private int listSize;
public int getListSize() {
return listSize;
}
public void setListSize(int listSize) {
this.listSize = listSize;
}
}
关于java - 如何设置 Jackson 反序列化以将 Base64 编码的字符串转换为 Controller 内的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59235032/