java - 无法将类型 id 解析为简单类型的子类型 - Spring Boot 中的内部枚举
问题描述
我开发了一个使用 React 作为前端,Spring Boot 作为后端的应用程序。当我尝试将 JSON 数据发送到 Spring Boot 时,出现以下异常:
2018-08-07 22:43:38.721 WARN 41036 --- [io-8080-exec-10]
.m.m.a.ExceptionHandlerExceptionResolver :
Resolved exception caused by Handler execution:
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error:
Could not resolve type id 'connectionTechnologyName' as a subtype of [simple type, class com.model.ConnectionTechnologyDetails]:
no such class found; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException:
Could not resolve type id 'connectionTechnologyName' as a subtype of [simple type, class com.model.ConnectionTechnologyDetails]:
no such class found at [Source: (PushbackInputStream); line: 1, column: 515] (through reference chain: com.payload.ConnectionRequest["connectionTechnologyDetails"])
Spring 正在为我的抽象类 ConnectionTechnologyDetails 的假定子类型 ConnectionTechnologyName 搜索类型 ID。所以 Spring 正在寻找一种继承。
抽象类 ConnectionTechnologyDetails 有一个 ConnectionTechnologyName 作为私有属性。ConnectionTechnologyName 的定义进一步是实体 ConnectionTechnologyDetails 的内部枚举。所以没有继承。我不知道有什么问题。
我的 React 应用程序的 JSON 请求由
以下 REST 端点:
/**
* Creates a new connection.
*/
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> createConnection(@RequestBody ConnectionRequest connectionRequest) {
logger.warn("ConnectionController: createConnection()");
try {
ContactDetails requestContactDetails = connectionRequest.getContactDetails();
ContactDetails persistedContactDetails = null;
if (connectionRequest.getContactDetails() != null) {
ContactDetails tmpContactDetails = new ContactDetails(
userRepository.findById(connectionRequest.getUser().getId()).get(),
requestContactDetails.getCompany(),
requestContactDetails.getAddress(),
requestContactDetails.getCity(),
requestContactDetails.getState(),
requestContactDetails.getCountry(),
requestContactDetails.getPostalCode(),
requestContactDetails.getCompanyContactPersons(),
requestContactDetails.getHlagContactPersons());
logger.warn("ConnectionController: createConnection() contactDetails created");
persistedContactDetails = contactDetailsRepository.save(tmpContactDetails);
logger.warn("ConnectionController: createConnection() conetactDetails saved");
}
// business case
if (connectionRequest.getBusinessCaseName() != null) {
String requestBusinessCaseName = connectionRequest.getBusinessCaseName();
logger.warn("ConnectionController: createConnection() businessCaseName got");
}
// connection technology details
if (connectionRequest.getConnectionTechnologyDetails().getConnectionTechnologyName().name() == "SMTP") {
SMTP requestConnectionDetails = (SMTP) connectionRequest.getConnectionTechnologyDetails();
SMTP smtp = new SMTP(ConnectionTechnologyDetails.ConnectionTechnologyName.SMTP,
requestConnectionDetails.getSenderReceiverIds(),
requestConnectionDetails.getSmtp());
logger.warn("ConnectionController: createConnection() SMTP created");
SMTP persistedSmtp = connectionTechnologyDetailsRepository.save(smtp);
logger.warn("ConnectionController: createConnection() SMTP saved");
Connection newConnection =
connectionRepository.save(new Connection(
userRepository.findById(connectionRequest.getUser().getId()).get(),
contactDetailsRepository.findById(persistedContactDetails.getId()).get(),
businessCaseRepository
.findByBusinessCaseName(connectionRequest.getBusinessCaseName()).get()
, connectionRequest.getEdiMessageStandard(),
connectionTechnologyDetailsRepository.findById(persistedSmtp.getId()).get()));
return ResponseEntity.created(new URI("api/connections/" + newConnection.getId())).build();
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
} catch (URISyntaxException e) {
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
}
@ResponseBody connectionRequest 定义为:
package com.payload;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.model.*;
import com.model.AuditInformation.AuditInformation;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* Class that represents a connection creation requests message.
*/
public class ConnectionRequest {
/**
* Foreign key of the user who created this connection. The user is independent from the connectioin.
*/
@NotNull
private ConnectionRequestUser user;
/**
* Foreign key for the contact details. They are independent from the connection.
*/
@NotNull
private ContactDetails contactDetails;
/**
* Business case of connection.
*/
@NotNull
private String businessCaseName;
/**
* Holds if ANSI or EDIFACT message type.
*/
@NotNull
private Connection.EdiMessageStandard ediMessageStandard;
/**
* Connection technique used for this connection
*/
@NotNull
private ConnectionTechnologyDetails connectionTechnologyDetails;
public ConnectionRequest(ContactDetails contactDetails, @NotBlank String businessCaseName,
Connection.@NotNull EdiMessageStandard ediMessageStandard,
ConnectionTechnologyDetails connectionTechnologyDetails,ConnectionRequestUser user) {
this.user = user;
this.contactDetails = contactDetails;
this.businessCaseName = businessCaseName;
this.ediMessageStandard = ediMessageStandard;
this.connectionTechnologyDetails = connectionTechnologyDetails;
}
public ConnectionRequest() {
}
public ConnectionRequestUser getUser() {
return user;
}
public void setUser(ConnectionRequestUser user) {
this.user = user;
}
public ContactDetails getContactDetails() {
return contactDetails;
}
public void setContactDetails(ContactDetails contactDetails) {
this.contactDetails = contactDetails;
}
public String getBusinessCaseName() {
return businessCaseName;
}
public void setBusinessCaseName(String businessCaseName) {
this.businessCaseName = businessCaseName;
}
public Connection.EdiMessageStandard getEdiMessageStandard() {
return ediMessageStandard;
}
public void setEdiMessageStandard(Connection.EdiMessageStandard ediMessageStandard) {
this.ediMessageStandard = ediMessageStandard;
}
public ConnectionTechnologyDetails getConnectionTechnologyDetails() {
return connectionTechnologyDetails;
}
public void setConnectionTechnologyDetails(ConnectionTechnologyDetails connectionTechnologyDetails) {
this.connectionTechnologyDetails = connectionTechnologyDetails;
}
}
连接技术详情
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
/**
* Represents common connection technology details.
*/
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "TECH_TYPE")
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_OBJECT, property = "@class")
@JsonSubTypes({
@JsonSubTypes.Type(value = AS2.class, name = "as2"),
@JsonSubTypes.Type(value = SMTP.class, name = "smtp"),
@JsonSubTypes.Type(value = FTP.class, name = "ftp"),
@JsonSubTypes.Type(value = FTPUnsec.class, name = "unsecFtp")
})
public abstract class ConnectionTechnologyDetails {
/**
* Unique id.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* To which connection the details belong.
*/
@OneToOne
@PrimaryKeyJoinColumn
@JsonIgnore
private Connection connection;
/**
* Name of the used technology.
*/
@NotNull
private ConnectionTechnologyName connectionTechnologyName;
/**
* Sender and receiver ids.
*/
@Embedded
private SenderReceiverIds senderReceiverIds;
public enum ConnectionTechnologyName {
SMTP,
AS2,
UNSECURE_FTP,
SECURE_FTP,
FTP_SECURE
}
/**
* Constructor
*
* @param connectionTechnologyName name of technology
* @param senderReceiverIds sender and receiver ids
*/
public ConnectionTechnologyDetails(ConnectionTechnologyName connectionTechnologyName, SenderReceiverIds senderReceiverIds) {
this.connectionTechnologyName = connectionTechnologyName;
this.senderReceiverIds = senderReceiverIds;
}
/**
* COnstructor
*/
public ConnectionTechnologyDetails() {
}
public ConnectionTechnologyName getConnectionTechnologyName() {
return connectionTechnologyName;
}
public void setConnectionTechnologyName(ConnectionTechnologyName connectionTechnologyName) {
this.connectionTechnologyName = connectionTechnologyName;
}
public SenderReceiverIds getSenderReceiverIds() {
return senderReceiverIds;
}
public void setSenderReceiverIds(SenderReceiverIds senderReceiverIds) {
this.senderReceiverIds = senderReceiverIds;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String toString() {
return "SenderAndReceiverIds: Name=" + getConnectionTechnologyName().name()
+ " SenderReceiverIds=" + getSenderReceiverIds();
}
}
我是否必须在 ConnectionTechnologyDetails 中的 ConnectionTechnologyName 属性上设置 @Embedded 注释?还是我必须为公共内部枚举本身设置注释?
解决方案
就我而言...我收到此错误是因为我在代码合并后将 codehaus 与 fastxml jackson 库混合在一起。
一旦我将它们切换到其中一个,它就可以正常工作。
推荐阅读
- reactjs - 映射函数在对象 React 中无法正常工作
- python - 使用 duaiterate.py 工具时与附加文件对应的错误
- python - 我正在使用 Google Colab,需要将一些文件从笔记本复制到我的驱动器。带通配符的命令是什么?(.ipynb 笔记本)
- javascript - 在 discord.js 中获取频道名称
- php - Google 日历 API 更新不会为已删除的事件返回错误
- jquery - 如何在电子中定义一个端点来监听一个发布请求?
- javascript - 连接丢失 - 套接字挂断
- visual-studio - 如何在 Visual Studio 中设置调试工作目录的默认路径
- matlab - 循环中的 if 语句
- next.js - Tailwind 的 JIT 模式在 Next JS 的本地主机预览中不起作用