参考资料
目录
一. 需求
项目中我们有可能调用第三方接口,返回数据。
⏹我们期待的数据为
{
"id": "110120119",
"name": "jiafeitian",
"address": "地球"
}
⏹但是第三方接口返回的数据为
{
"id": "110120119",
"name": "jiafeitian",
"humanAddress": "地球"
}
😵由于返回的数据中有部分不符合我们的需求,因此需要手动get
和set
一下,
如果项目中有多个地方都需要调用此接口,那么每调用一次都需要手动修改一下。
entity.setAddress(apiEntity.getHumanAddress());
二. 前期准备
⏹前台发送请求
$.ajax({
url: "/test01/getCardInfo1",
type: 'POST',
data: null,
contentType: 'application/json;charset=utf-8',
success: function (data, status, xhr) {
debugger;
console.log(data);
}
});
⏹第三方接口与第三方实体类
- 第三方实体类
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Card {
private String id;
private String name;
private String mobile;
}
- 模拟第三方接口
import org.springframework.stereotype.Service;
@Service
public class Test01Service {
// 第三方接口的方法
public Card getCardInfo() {
return Card.builder()
.id("110")
.name("Test")
.mobile("110120119")
.build();
}
}
三. 解决方式一: @JsonProperty注解
- 将该注解直接作用于实体类上,标记想要返回的key
- 此情况适用于能修改其他包实体类的情况下,部分jar包中的代码我们无法修改
- 在实际业务中,部分代码可能不允许修改
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Card {
private String id;
private String name;
// 标记我们想要返回的key的名称
@JsonProperty("jmw_phone")
private String mobile;
}
⏹调用
@Controller
@RequestMapping("/test01")
public class Test01Controller {
@Resource
private Test01Service service;
@PostMapping("/getCardInfo1")
@ResponseBody
public Card getCardInfo1() {
Card cardInfo = service.getCardInfo();
return cardInfo;
}
}
💪可以看到,最终返回的是jmw_phone
,而不是mobile
。
三. 解决方式二: @JsonProperty + @JsonMixin注解
⏹ @JsonMixin
注解是Spring Boot 2.7.x
之后出现的新特性,可以在不修改已有的Java类库的情况下,定制Json的输出。
3.1 方式1 混入单个类
3.1.1 创建一个被@JsonMixin注解修饰的抽象类
- Spring Boot的Jackson自动配置将扫描应用程序的包以查找带有
@JsonMixin
注解的类,
并将它们注册到自动配置的ObjectMapper
中。 - 我们通过
@JsonMixin
注解将Card.class
这个类混入到CardWarp
中,然后在指定需要被定制的属性中使用@JsonProperty
注解来修改返回json时的key。
import org.springframework.boot.jackson.JsonMixin;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@JsonMixin(Card.class)
public abstract class CardWarp {
// 自定义返回json的key
@JsonProperty("jmw_phone")
private String mobile;
}
3.1.2 调用查看效果
@Controller
@RequestMapping("/test01")
public class Test01Controller {
@Resource
private Test01Service service;
@PostMapping("/getCardInfo2")
@ResponseBody
public Card getCardInfo2() {
Card cardInfo = service.getCardInfo();
return cardInfo;
}
}
💪可以看到,我们只是新创建了CardWarp
,并没有对Card
类进行任何改动,
依然能实现效果。
3.2 方式2 混入多个类
3.2.1 第三方接口中的类
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Card {
private String id;
private String name;
private String mobile;
}
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Person {
private String personId;
private String humanName;
private String age;
}
3.2.2 @JsonMixin注解混入多个类
import org.springframework.boot.jackson.JsonMixin;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@JsonMixin({Card.class, Person.class})
public abstract class CardWarp {
// 将Card中的mobile修改为jmw_phone
@JsonProperty("jmw_phone")
private String mobile;
// 将Person中的humanName修改为personName
@JsonProperty("personName")
private String humanName;
}
3.2.3 定义实体类组合第三方接口中的类
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Test02Entity {
private String uuid;
// 组合Card 类
private Card card;
// 组合person类
private Person person;
}
3.2.4 调用查看效果
@Controller
@RequestMapping("/test01")
public class Test01Controller {
@Resource
private Test01Service service;
@PostMapping("/getCardInfo3")
@ResponseBody
public Test02Entity getCardInfo3() {
return Test02Entity.builder()
.uuid("X6u8iy&y")
.card(Card.builder().id("10").mobile("15165244").name("测试").build())
.person(Person.builder().personId("20").humanName("贾飞天").age("100").build())
.build();
}
}
💪可以看到,我们的对key的修改起到了效果