gpt4 book ai didi

java - 将整个类序列化为字符串字段而不是 JSON 对象

转载 作者:行者123 更新时间:2023-11-30 09:00:57 24 4
gpt4 key购买 nike

我有一个对象,它使用类实例作为 String 类型的包装器。我如何通过仅使用 toString() 方法使用 JAX-RS 和 Java EE 6 将我的类序列化为 JSON 对象,而不为类和每个字段创建 JSON 对象?

要序列化的类:

public class Text {
private String content;
protected Text( String content ) {
this.content = content;
}
public static Text from( String content ) {
return new Text( "The text content");
}
// This is a method that is used by the subclass and has no meaning for serialization
protected String getContent() {
return content;
}
// This should be used to serialize this class into a String, instead of an object
@Override
public String toString() {
return content;
}
}

使用待序列化类的父类:

public class EditorStoryChapterInput {
private Text title;
public Text getTitle() {
return title;
}
}

预期结果:我想序列化为 { "title": "The text content"} 而不是 { "title": { content: "the text content"} }/.

编辑:查看 Jackson 常见问题解答,我发现了一些有用的东西,我想要的可能与我发现的相同,但是在 中的 JAX-RS/Java EE 6 环境中 JBoss EAP 6.1。在我使用 JBoss EAP 6.1 的类路径中没有 @JsonValue:

http://wiki.fasterxml.com/JacksonFAQ#Serializing_values_as_simple_types

最佳答案

来自评论:

I don't know about spec compliant, but I just tested it, adding the Jackson dependency to my project, and just putting the @JsonValue over the toString() like mentioned in the link, and it works fine. Like I said, JBoss is using Jackson under the hood to do the serializing. So there's nothing wrong with using it in your project. You just need to add the dependency in order to compile the annotation. You can get it straight from the server modules if you need to do. But it'll be easier to just use Maven

以下是我在示例中使用的类。我将发布类,然后指出如何获取依赖项。

你的 Text

/** Getter and Setters added for Jackson discovery **/
public class Text {

private String content;

public void setContent(String content) { this.content = content; }
protected String getContent() { return content; }

@Override @JsonValue
public String toString() { return content; }
}

你的 EditorStoryChapterInput

public class EditorStoryChapterInput {

private Text title;

public void setTitle(Text title) { this.title = title; }
public Text getTitle() { return title; }
}

资源类

@Path("/json")
public class JsonResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getJson() {
EditorStoryChapterInput input = new EditorStoryChapterInput();
Text title = new Text();
title.setContent("Hello World");
input.setTitle(title);
return Response.ok(input).build();
}
}

注册资源的Application

@ApplicationPath("/rest")
public class JsonApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(JsonResource.class);
return classes;
}
}

结果

enter image description here

获取依赖项

如果您使用的是 Maven,则只需要 jackson-core-asl 工件。我用JBoss的时候比较喜欢用他们的boms,这样他们可以管理版本。所以你的 pom 看起来像什么(记住我说过我们可以使用 provide 范围,因为 JBoss 已经有了这些依赖项。我们只需要它来编译)

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-resteasy</artifactId>
<version>1.0.7.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<scope>provided</scope>
</dependency>
... Other dependencies
</dependencies>

如果你没有使用 Maven,你可以简单地看看里面

${eap-home-dir}\modules\system\layers\base\org\codehaus\jackson\jackson-core-asl\main

在那里你会找到jackson-core-asl-1.9.9.redhat-3.jar。只需将其添加到您的项目中,但您通常会将 jars 添加到您的项目中。测试了这种方法,结果相同

enter image description here

如果您在添加依赖项时遇到任何问题,请告诉我。


更新:不使用 Jackson(无第三方依赖项)

我们可以使用 Java API for JSON Processing ,并实现我们自己的 MessageBodyWriter ,它将用于将 EditorStoryChapterInput 对象写入响应 OutputStream。它可能看起来像

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class TextMessageBodyWriter
implements MessageBodyWriter<EditorStoryChapterInput> {

@Override
public boolean isWriteable(Class type, Type type1,
Annotation[] antns, MediaType mt) {
return type == EditorStoryChapterInput.class;
}

@Override
public long getSize(EditorStoryChapterInput t, Class<?> type,
Type type1, Annotation[] antns, MediaType mt) {
return -1;
}

@Override
public void writeTo(EditorStoryChapterInput input, Class<?> type,
Type type1, Annotation[] antns, MediaType mt,
MultivaluedMap<String, Object> mm, OutputStream out)
throws IOException, WebApplicationException {

Text title = input.getTitle();
JsonObject jsonObject =
Json.createObjectBuilder()
.add("title", title.toString()).build();

try (JsonWriter jsonWriter = Json.createWriter(out)) {
jsonWriter.writeObject(jsonObject);
}
}
}

当搜索 MessageBodyWriters 时,JAX-RS 将查看 @Produces 注释以查看它生成的类型,以及它是否与 @Produces 方法在我们的资源方法上,编写器将被放入一个列表中供框架遍历。接下来它将检查每个写入器的 isWritable 方法。如果它返回 true,那么这就是它将使用的编写器。在我们的例子中,如果响应主体的返回类型是 EditorStoryChapterInput 类型,我们将返回 true。

writeTo方法中,我们使用Java JSON Processing API创建一个JsonObject,并将其写入到OutputStream中框架。

然后我们可以在应用程序中注册作者

@ApplicationPath("/rest")
public class TextApplication extends Application {

@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<>();
classes.add(JsonResource.class);
classes.add(TextMessageBodyWriter.class);
return classes;
}
}

使用上面相同的 JsonResource 类对其进行测试,我们得到了输出

{"title":"Hello World"}

关于java - 将整个类序列化为字符串字段而不是 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26578239/

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