Tag*_*a85 3 java spring jackson spring-boot
我正在使用 Spring Boot 应用程序。
我的控制器中有一个方法可以返回一些资源:
@ResponseBody
@Transactional(rollbackFor = Exception.class)
@GetMapping(value="data/{itemId}/items", produces="application/json")
public Resources<DataExcerpt> listMyData(@PathVariable("debateId") UUID debateId)){
List<DataExcerpt> dataExcerpts = dataService
.listMyData(id)
.stream()
.map(d -> this.projectionFactory.createProjection(DataExcerpt.class, d))
.collect(Collectors.toList());
return new Resources<>(dataExcerpts);
}
Run Code Online (Sandbox Code Playgroud)
这以以下形式返回:
{
"_embedded" : {
"items" : [ {
"position" : {
"name" : "Oui",
"id" : "325cd3b7-1666-4c44-a55f-1e7cc936a3aa",
"color" : "#51B63D",
"usedForPositionType" : "FOR_CON"
},
"id" : "5aa48cfb-5505-43b6-b0a9-5481c895e2bf",
"item" : [ {
"index" : 0,
"id" : "43c2dcd0-6bdb-43b0-be97-2a40b99bc753",
"description" : {
"id" : "021ad7cd-4bf1-4dce-9ea7-10980440a049",
"title" : "Item description",
"modificationCount" : 0
}
} ],
"title" : "Item title",
"originalMaker" : {
"username" : "jeremieca",
"id" : "cfae1a04-cb00-4ad4-b4e8-6971eff64807",
"avatarUrl" : "user-16",
"_links" : {
"self" : {
"href" : "http://some-api-link"
}
}
},
"itemState" : {
"itemState" : "LIVE",
},
"opinionImprovements" : [ ],
"sourcesJson" : [ ],
"makers" : [ {
"username" : "jeremieca",
"id" : "cfae1a04-cb00-4ad4-b4e8-6971eff64807",
"avatarUrl" : "user-16",
"_links" : {
"self" : {
"href" : "http://some-api-link"
}
}
} ],
"modificationsCounter" : 1,
"originalBuyer" : "fd9b68f9-7c0c-4120-869c-c63d1680e7f0",
"updateTrace" : {
"createdOn" : "2020-05-25T08:12:56.846+0000",
"createdBy" : "cfae1a04-cb00-4ad4-b4e8-6971eff64807",
"updatedOn" : "2020-05-25T08:12:56.845+0000",
"updatedBy" : "cfae1a04-cb00-4ad4-b4e8-6971eff64807"
},
"_links" : {
"self" : {
"href" : "some-api-link",
"templated" : true
},
"newEditions" : {
"href" : "some-api-link",
"templated" : true
},
"makers" : {
"href" : "http://some-api-link"
},
"originalMaker" : {
"href" : "http://some-api-link"
}
}
} ]
}
}
Run Code Online (Sandbox Code Playgroud)
另一方面,我也想将这些答案缓存在 Redis 中,以避免每次都运行整个过程。为此,我使用 Jackson 的 ObjectMapper 将我的资源转换为字符串
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValueAsString(controller.listMyData(id)); // the same function as above
Run Code Online (Sandbox Code Playgroud)
writeValueAsString输出的结构与第一个不同:
"{content: [...], _links: []}"
Run Code Online (Sandbox Code Playgroud)
因此,当我从带有缓存内容的 API 返回时,结构与控制器在没有缓存的情况下发送给我的结构不同。
这是为什么?Jackson 是否无法正确地将 Resources Hateoas 结构写为字符串?我错过了什么吗?
编辑:
这是 Resources.class:
package org.springframework.hateoas;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import org.springframework.util.Assert;
@XmlRootElement(name = "entities")
public class Resources<T> extends ResourceSupport implements Iterable<T> {
private final Collection<T> content;
protected Resources() {
this(new ArrayList(), (Link[])());
}
public Resources(Iterable<T> content, Link... links) {
this(content, (Iterable) Arrays.asList(links));
}
public Resources(Iterable<T> content, Iterable<Link> links) {
Assert.notNull(content, "Content must not be null!");
this.content = new ArrayList();
Iterator var3 = content.iterator();
while (var3.hasNext()) {
T element = var3.next();
this.content.add(element);
}
this.add(links);
}
public static <T extends Resource<S>, S> Resources<T> wrap(Iterable<S> content) {
Assert.notNull(content, "Content must not be null!");
ArrayList<T> resources = new ArrayList();
Iterator var2 = content.iterator();
while (var2.hasNext()) {
S element = var2.next();
resources.add(new Resource(element, new Link[0]));
}
return new Resources(resources, new Link[0]);
}
@XmlAnyElement
@XmlElementWrapper
@JsonProperty("content")
public Collection<T> getContent() {
return Collections.unmodifiableCollection(this.content);
}
public Iterator<T> iterator() {
return this.content.iterator();
}
public String toString() {
return String.format("Resources { content: %s, %s }", this.getContent(), super.toString());
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj != null && obj.getClass().equals(this.getClass())) {
Resources<?> that = (Resources) obj;
boolean contentEqual = this.content == null ? that.content == null : this.content.equals(that.content);
return contentEqual ? super.equals(obj) : false;
} else {
return false;
}
}
public int hashCode() {
int result = super.hashCode();
result += this.content == null ? 0 : 17 * this.content.hashCode();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你。
原因是当 Spring 使用 HATEOAS 配置您的 MVC 或 Spring Boot 应用程序时,它会配置自定义 Jackson 模块来处理类的序列化和反序列化过程Resources以及 API 公开的其余对象模型。
如果要获得类似的结果,可以执行以下操作:
import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
// ...
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
objectMapper.writeValueAsString(controller.listMyData(id));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
266 次 |
| 最近记录: |