gpt4 book ai didi

java - Jackson 自定义反序列化器在 Spring Boot 中无法工作

转载 作者:行者123 更新时间:2023-12-01 16:44:55 24 4
gpt4 key购买 nike

我为我的实体创建了一个自定义反序列化器,但它不断抛出异常:

我有两个类:AppUser 和 AppUserAvatar

AppUser.java

@Entity
@Table(name = "user")
public class AppUser implements Serializable {

@Transient
private static final long serialVersionUID = -3536455219051825651L;

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(name = "password", nullable = false, length = 256)
private String password;

@JsonIgnore
@Column(name = "is_active", nullable = false)
private boolean active;

@JsonIgnore
@OneToMany(mappedBy = "appUser", targetEntity = AppUserAvatar.class, fetch = FetchType.LAZY)
private List<AppUserAvatar> appUserAvatars;

//// Getters and Setters and toString() ////
}

AppUserAvatar.java

@Entity
@Table(name = "user_avatar")
public class AppUserAvatar extends BaseEntityD implements Serializable {

@Transient
private static final long serialVersionUID = 8992425872747011681L;

@Column(name = "avatar", nullable = false)
@Digits(integer = 20, fraction = 0)
@NotEmpty
private Long avatar;

@JsonDeserialize(using = AppUserDeserializer.class)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private AppUser appUser;

//// Getters and Setters and toString() ////
}

AppUserDeserializer.java包 com.nk.accountservice.deserializer;

import com.edoctar.accountservice.config.exception.InputNotFoundException;
import com.edoctar.accountservice.domain.candidate.AppUser;
import com.edoctar.accountservice.service.candidate.AppUserService;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.Serializable;

public class AppUserDeserializer extends JsonDeserializer implements Serializable {

private static final long serialVersionUID = -9012464195937554378L;

private AppUserService appUserService;

@Autowired
public void setAppUserService(AppUserService appUserService) {
this.appUserService = appUserService;
}

@Override
public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
Long userId = node.asLong();
System.out.println(node);
System.out.println(node.asLong());
AppUser appUser = appUserService.findById(userId);
System.out.println("appuser: " + appUser);
if (appUser == null) try {
throw new InputNotFoundException("User not found!");
} catch (InputNotFoundException e) {
e.printStackTrace();
return null;
}

return appUser;
}
}

示例 xhr boy 是:

{
"appUser": 1,
"avatar": 1
}

每次提交请求时都会引发异常。

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.edoctar.accountservice.domain.candidate.AppUserAvatar["appUser"])]

Here's the screenshoot of my console.

我发现 appUserService.findById() 方法没有被调用。我真的很困惑。我不知道我哪里错了。对于任何解决方案将不胜感激。谢谢。

最佳答案

更新的答案:您不能使用 Autowiring 属性,因为您不在 Spring 上下文中。您正在将类 AppUserDeserializer 作为注释中的引用传递

@JsonDeserialize(using = AppUserDeserializer.class)

在这种情况下,FasterJackson 库创建了 AppUserDeserializer 实例,因此不考虑 Autowired 注释。

用一个小技巧就可以解决你的问题。在AppUserService中添加对spring创建的实例的静态引用:

 @Service
public AppUserService {

public static AppUserService instance;

public AppUserService() {
// Modify the constructor setting a static variable holding a
// reference to the instance created by spring
AppUserService.instance = this;
}

...
}

AppUserDeserializer中使用该引用:

public class AppUserDeserializer extends JsonDeserializer implements Serializable {

private AppUserService appUserService;

public AppUserDeserializer() {
// Set appUserService to the instance created by spring
this.appUserService = AppUserService.instance;
}

...

}
<小时/>

原始答案:要正确初始化Autowired属性,您必须注释您的类AppUserDeserializer,否则appUserService如果您不要使用 set 方法显式初始化它。

尝试使用 @Component 注释 AppUserDeserializer:

@Component   // Add this annotation
public class AppUserDeserializer extends JsonDeserializer implements Serializable {
...
}

关于java - Jackson 自定义反序列化器在 Spring Boot 中无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53667217/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com