文档章节

Spring 转换 model 为 json 时增加属性

郁也风
 郁也风
发布于 2018/09/23 18:28
字数 571
阅读 805
收藏 0

阿里云携手百名商业领袖、技术大咖,带您一探行进中的数字新基建!>>>

缘起

目前的项目中有个需求是在附件对象转换成 json 时增加个 url 属性,以前的方式是在返回附件对象或列表时候做一次统一处理,这次想看看 spring 或者 jackson fasterxml 是否自带类似功能,结果一查,还真有。

当前业务系统的处理附件的方式是上传附件之后将其基本信息统一存储到附件表中,然后通过相应的 url 拼接附件 id 的方式来读取相应附件(以便更方便控制授权),也就是说将附件对象返回前端的时候需要将其 url 也放置到 json 中,但是这个 url 属性并不在基本信息中存在。

实现

查了一下,发现 @JsonAppend 完全可以满足这个需要。

@JsonAppend 在 jackson fasterxml 中是通过 VirtualBeanPropertyWriter 来处理的。

首先构造一个 mixin 接口,在其上配置 @JsonAppend:

@JsonAppend(
    props = {
        @JsonAppend.Prop(name = "url", value = AttachmentUrl.class),
    }
)
public interface AttachmentMixin {
}

之后就是实现 VirtualBeanPropertyWriter 的子类,在这儿可以通过 @Autowired 注入相应的处理方法:

public class AttachmentUrl extends VirtualBeanPropertyWriter {

    private static final long serialVersionUID = 1028128817195205673L;

    @Autowired UrlService urlService;

    public AttachmentUrl() {
    }

    public AttachmentUrl(BeanPropertyDefinition propDef,
        Annotations contextAnnotations,
        JavaType declaredType, UrlService urlService) {
        super(propDef, contextAnnotations, declaredType);

        this.urlService = urlService;
    }

    @Override
    protected Object value(Object bean, JsonGenerator gen, SerializerProvider prov) {

        if (urlService != null) {
            return urlService.getAttachUrl((Attachment) bean);
        }
        return null;
    }

    @Override
    public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config,
        AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type) {
        return new AttachmentUrl(propDef, null, type, urlService);
    }
}

注意:在 withConfig 方法中会创建新的对象,这个对象 return new AttachmentUrl(propDef, null, type, urlService);,这儿的 urlService不能使用 this.urlService, 因为urlService 是 spring 通过默认构造函数注入的,如果使用 this,则会成为 null。

最后配置 Jackson2ObjectMapperBuilderCustomizer

@Configuration
public class JacksonConfiguration {

    /**
     * 自定义 {@link Jackson2ObjectMapperBuilder}.
     *
     * @return 略
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() {
        return builder -> builder.mixIn(Attachment.class, AttachmentMixin.class);
    }
}

原理

spring 通过 org.springframework.http.converter.json.SpringHandlerInstantiator 实现对于 jackson fasterxml 的配置,也就是说在此处注入相应的 bean,对于 @JsonAppend 的处理方法为:

@Override
	public VirtualBeanPropertyWriter virtualPropertyWriterInstance(MapperConfig<?> config, Class<?> implClass) {
		return (VirtualBeanPropertyWriter) this.beanFactory.createBean(implClass);
	}

Over

© 著作权归作者所有

郁也风
粉丝 16
博文 31
码字总数 17009
作品 0
长宁
项目经理
私信 提问
加载中

评论(0)

Spring MVC-学习笔记(3)参数绑定注解、HttpMessageConverter<T>信息转换、jackson、fastjson、XML

1、参数绑定注解 1》@RequestParam: 用于将指定的请求参数赋值给方法中的指定参数。支持的属性: 2》@PathVariable:可以方便的获得URL中的动态参数,只支持一个属性value,类型为String,表...

osc_cesboqi4
2019/08/21
3
0
spring接收json格式的多个对象参数(变通法)

两种方法 方法1 如果使用spring mvc同客户端通信,完全使用json数据格式,需要增加RequestBody注解,函数参数为自定义类 @Controllerpublic class TestController{@RequestMapping("test")@R...

xiaomin0322
2019/02/27
45
1
SpringBoot整合WEB开发--(一)处理JSON返回数据

1.使用默认的json转换HttpessageConverter Json是目前主流的前后端数据传输方式,SpringMVC中使用消息转化器HttpMessageConverter对JSON的转换提供了很好的支持,在SpringBoot中对相关配置做...

osc_8g67o6g0
02/15
20
0
Spring MVC 学习总结(三)——请求处理方法Action详解

Spring MVC 学习总结(三)——请求处理方法Action详解 目录 一、Action参数类型 1.1、自动参数映射 1.1.1、基本数据类型 1.1.2、自定义数据类型 1.1.3、复杂数据类型 1.1.4、List集合类型 ...

osc_srt16prk
2018/07/24
3
0
SpringMVC之ajax传递jason数据详解以及@RequestBody和@ResonseBody注解

最近在做ajax进行用户名校验时遇到了一些问题,在不断debug的过程中也加深了我对springMVC之ajax传递jason数据的理解,希望对有需要的小伙伴一些帮助~ 工具:IDEA 我们通过code来理解一下: ...

osc_cnpchqmq
2019/07/31
4
0

没有更多内容

加载失败,请刷新页面

加载更多

什么是 PL/SQL? 怎么用?

PL/SQL 1.什么是PL/SQL? PL/SQL(Procedure Language/SQL)是Oracle对sql语言的过程化扩展,指在SQL命令语言中增加了过程处理语句(如分支/条件、循环、变量、类型等),使SQL语言具有过程处...

煌sir
7分钟前
13
0
dayjs时间处理库基本使用

Day.js 是一个轻量的 JavaScript 时间日期处理库,与 Moment.js 的 API 设计保持一致。 本文只介绍了一些常用操作,关于国际化、插件、自定义等高级内容详见官方文档。 其主要特性如下: 与 ...

whoru
10分钟前
11
0
Delphi xe使用TJSONObject解析JSON数据

在Delphi 10 Seattle中重写 “ 使用TJSONObject分析JSON数据 ”。 由于不推荐使用某些方法,因此已对其进行了更改。 要使用TJSONObject,请添加“ System.JSON”。 uses System.JSON; 使用T...

simpower
20分钟前
11
0
树莓派使用 OLED 屏显示图片及文字

树莓派默认是不带显示屏的,如果想要查看系统的一些信息,需要使用电脑登录到树莓派,或者通过 HDMI 连接外接显示器查看。这样做总是有点麻烦,我们可以通过外接一个 OLED 屏来显示一些关键参...

良许Linux
23分钟前
7
0
BIO学习

1. BIO介绍 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程...

steven-黄笑笑
25分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部