我正在开发基于 JAX-RS 的应用程序和 Payara 服务器。我想将 java Color 类中的构建序列化为字符串格式:
color
= "RcolorValu, GColorValue, BColor
值”。例如以 "255,255,255"
形式。这就是我编写自定义序列化程序的原因:
package org.example;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.awt.*;
import java.io.IOException;
import java.util.logging.Logger;
public class ColorSerializer extends JsonSerializer<Color> {
private static final Logger logger = Logger.getLogger(ColorSerializer.class.getName());
@Override
public void serialize(Color color, JsonGenerator generator, SerializerProvider serializers) throws IOException {
logger.info("Serializing color init ");
if (color == null) {
generator.writeNull();
} else {
String colorString = color.getRed() + "," + color.getGreen() + "," + color.getBlue();
logger.info("Serializing color: " + colorString); // Add logging
generator.writeString(colorString);
}
}
}
我也在
ObjectMapperProvider
中注册了它,如下所示:
package org.example;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
import java.awt.*;
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper objectMapper;
public ObjectMapperProvider() {
// Register the JavaTimeModule for date/time serialization
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// Register the custom ColorSerializer
SimpleModule module = new SimpleModule();
module.addSerializer(Color.class, new ColorSerializer());
objectMapper.registerModule(module);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return objectMapper;
}
}
我的 Employee 实体类具有
favoriteColor
属性和注释 @JsonSerialize(using = ColorSerializer.class)
,它应该导致序列化,其形式如下:
package org.example;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import jakarta.json.bind.annotation.JsonbDateFormat;
import jakarta.persistence.*;
import java.awt.*;
import java.io.Serializable;
import java.util.Date;
@Entity
@Table(name = "Employee")
public class Employee implements Serializable {
@Id
@Column(name = "EMPLOYEE_ID")
private Long id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
@Column(name = "HIRE_DATE")
@Temporal(TemporalType.DATE)
@JsonbDateFormat("yyyy-MM-dd")
private Date hireDate;
@Column(name = "GENDER")
@Enumerated(EnumType.STRING)
private Gender gender;
public Color getFavoriteColor() {
return favoriteColor;
}
public void setFavoriteColor(Color favoriteColor) {
this.favoriteColor = favoriteColor;
}
@Column(name = "FAVORITE_COLOR")
@Convert(converter = ColorConverter.class)
@JsonSerialize(using = ColorSerializer.class)
private Color favoriteColor;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
}
我的 EmployeeResource 包含员工端点列表,应返回员工列表:
package org.example;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
import java.util.logging.Logger;
@Path("/employee")
@RequestScoped
public class EmployeeResource {
@Inject
private EmployeeService employeeService;
private static final Logger logger = Logger.getLogger(EmployeeService.class.getName());
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/")
public List<Employee> getEmployees() {
logger.info("Retrieving all employees");
return employeeService.getAllEmployees();
}
}
除此之外,我配置了可以工作的转换器。我从日志中找出了它,但序列化器没有:
package org.example;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.awt.*;
import java.util.logging.Logger;
@Converter(autoApply = true)
public class ColorConverter implements AttributeConverter<Color, String> {
private static final Logger logger = Logger.getLogger(ColorSerializer.class.getName());
@Override
public String convertToDatabaseColumn(Color attribute) {
logger.info("converter color color: " + attribute.toString()); // Add logging
return attribute.getRed() +
"," +
attribute.getGreen() +
"," +
attribute.getBlue();
}
@Override
public Color convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.isBlank()) {
return null;
}
String[] parts = dbData.split(",");
Color color = new Color(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
logger.info("Converting DB data to color: " + color.toString()); // Add logging
return color;
}
}
无论如何,我每次都会收到 json 响应,例如:
数据库中的示例数据:
我不知道如何利用我的自定义序列化器而不是内置。
您在同一应用程序中混合 JSON-Binding 和 Jackson 注释。 JSON-Binding 注释位于以
jakarta.json.bind.annotation
开头的包中,例如代码中的 JsonbDateFormat
注释。 Jackson 注释位于以 com.fasterxml.jackson
开头的包中,例如JsonSerialize
。您只能使用其中之一,而不能同时使用两者。 Payara 不支持开箱即用的 Jackson 注释。如果启用 Jackson,则 JSON-Binding 注释将被忽略,因为 Jackson 不支持 JSON-Binding。
了解您是否使用标准 JSON 绑定或启用了 Jackson(如此处所述)。如果您没有启用 Jackson,则
JsonSerialize
注释和 ObjectMapperProvider
中的所有 Jackson 配置都将被忽略。那么你应该在 JSON-Binding 中使用 JsonbSerializer
来代替。它记录在 Jakarta EE 教程中:https://jakarta.ee/learn/docs/jakartaee-tutorial/current/web/jsonb/jsonb.html#_using_customizations
或者您应该启用 Jackson 并用 Jackson 支持的等效内容替换
JsonbDateFormat
注释和其他 JSON-B 注释。
您的
ColorConverter
类是持久实体的转换器。当数据存储到数据库时使用它。当为 REST 响应构建 JSON 时,它会被忽略。