java - 如何设置 Jackson 反序列化以将 Base64 编码的字符串转换为 Controller 内的对象

标签 java spring-boot jackson

环境:
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/

相关文章:

spring - @Cacheable 注解给出 404

java - 从 JSON 中的多值元素中过滤单个元素

java - 支持 Jackson @JsonFilter 异步 DeferredResult

java - 插入带有子项的@OneToMany 关系对象而不在子表中插入父项ID?

java - 使用 Jackson 对非基元进行序列化

java字母游戏[家庭作业]

java - DatagramSocket.send 线程安全吗?

java - 有没有办法监控SES等指定AWS服务的健康状态?

java - 找不到符号 Line2D?

mysql - 使用 maria DB、JPA 和 Spring Boot 1.5.4 基于架构的 Multi-Tenancy