使用Spring数据REST公开枚举
我使用的是SpringBoot1.5.3,SpringDataREST,HATEOAS。 我有一个简单的实体模型:使用Spring数据REST公开枚举,spring,rest,spring-mvc,spring-data-rest,Spring,Rest,Spring Mvc,Spring Data Rest,我使用的是SpringBoot1.5.3,SpringDataREST,HATEOAS。 我有一个简单的实体模型: @Entity public class User extends AbstractEntity implements UserDetails { private static final long serialVersionUID = 5745401123028683585L; public static final PasswordEncoder PASSWORD_ENCODE
@Entity
public class User extends AbstractEntity implements UserDetails {
private static final long serialVersionUID = 5745401123028683585L;
public static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
@NotNull(message = "The name of the user cannot be blank")
@Column(nullable = false)
private String name;
/** CONTACT INFORMATION **/
private String landlinePhone;
private String mobilePhone;
@NotNull(message = "The username cannot be blank")
@Column(nullable = false, unique = true)
private String username;
@Email(message = "The email address is not valid")
private String email;
@JsonIgnore
private String password;
@Column(nullable = false)
private String timeZone = "Europe/Rome";
@JsonIgnore
private LocalDateTime lastPasswordResetDate;
@Column(nullable = false, columnDefinition = "BOOLEAN default true")
private boolean enabled = true;
@Type(type = "json")
@Column(columnDefinition = "json")
private Roles[] roles = new Roles[] {};
我的枚举角色是:
public enum Roles {
ROLE_ADMIN, ROLE_USER, ROLE_MANAGER, ROLE_TECH;
@JsonCreator
public static Roles create(String value) {
if (value == null) {
throw new IllegalArgumentException();
}
for (Roles v : values()) {
if (value.equals(v.toString())) {
return v;
}
}
throw new IllegalArgumentException();
}
}
我正在Angular 4中创建一个客户端。Spring Data REST非常好,并且可以轻松地将存储库公开并返回符合我的模型HATEOAS:
{
"_embedded": {
"users": [
{
"name": "Administrator",
"username": "admin",
"roles": [
"Amministratore"
],
"activeWorkSession": "",
"_links": {
"self": {
"href": "http://localhost:8080/api/v1/users/1"
},
"user": {
"href": "http://localhost:8080/api/v1/users/1{?projection}",
"templated": true
}
}
},
正如您所看到的,我也在通过rest-messages进行翻译。属性是我的枚举的值。伟大的
我的Angular页面现在需要完整的角色列表(枚举)。我有一些问题:
- 了解服务器返回角色列表的更好方法
- 如何返回此列表
@RepositoryRestController
@RequestMapping(path = "/api/v1")
公共类用户控制器{
@Autowired
private EntityLinks entityLinks;
@RequestMapping(method = RequestMethod.GET, path = "/users/roles", produces = "application/json")
public Resource<Roles> findRoles() {
Resource<Roles> resource = new Resource<>(Roles.ROLE_ADMIN);
return resource;
}
@Autowired
私有实体链接实体链接;
@RequestMapping(method=RequestMethod.GET,path=“/users/roles”,products=“application/json”)
公共资源findRoles(){
资源=新资源(Roles.ROLE\u ADMIN);
返回资源;
}
不幸的是,由于某种原因,对这个方法的调用返回了404错误。我调试了,并且正确地创建了资源,所以我猜问题出在JSON转换的某个地方
如何返回此列表
@RepositoryRestController
@请求映射(“/roles”)
公共类角色控制器{
@GetMapping
公共响应性getAllRoles(){
列表内容=新建ArrayList();
content.addAll(Arrays.asList(
新资源(Roles.ROLE1/*,可选链接*/),
新资源(Roles.ROLE2/*,可选链接*/);
返回ResponseEntity.ok(新资源(内容/*,可选链接*/);
}
}
我一直在玩这个游戏,并找到了几种方法
假设您有一个前端表单,它希望显示一个组合框,其中包含单个Todo的优先级,例如高、中、低
。该表单需要知道主键或id
,这是此实例中的枚举值,该值应为组合框应显示的可读格式值
如果您希望仅在一个位置自定义json响应,例如单个端点,那么我发现这很有用。秘密酱汁使用value对象PriorityValue
,允许您通过@Relation
重命名json字段
public enum Priority {
HIGH("High"),
NORMAL("Normal"),
LOW("Low");
private final String description;
Priority(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public static List<Priority> orderedValues = new ArrayList<>();
static {
orderedValues.addAll(Arrays.asList(Priority.values()));
}
}
@RepositoryRestController
@RequestMapping(value="/")
public class PriorityController {
@Relation(collectionRelation = "priorities")
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
private class PriorityValue {
private String id;
private String value;
public PriorityValue(String id,
String value) {
this.id = id;
this.value = value;
}
}
@GetMapping(value = "/api/priorities", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity<Resources<PriorityValue>> getPriorities() {
List<PriorityValue> priorities = Priority.orderedValues.stream()
.map(p -> new PriorityValue(p.name(), p.getDescription()))
.collect(Collectors.toList());
Resources<PriorityValue> resources = new Resources<>(priorities);
resources.add(linkTo(methodOn(PriorityController.class).getPriorities()).withSelfRel());
return ResponseEntity.ok(resources);
}
}
来自http://localhost:8080/api/priorities
{
"_embedded": {
"priorities": [
{
"id": "HIGH",
"value": "High"
},
{
"id": "NORMAL",
"value": "Normal"
},
{
"id": "LOW",
"value": "Low"
}
]
},
"_links": {
"self": {
"href": "http://localhost:8080/api/priorities"
}
}
}
在我看来,最好的方法是将您的角色从枚举转换为实体。我明白了,但似乎有些过分。按照这个想法,每个枚举都将成为一个枚举…因此我不认为枚举有什么意义。相反,我认为枚举非常有用,尤其是在这些情况下。
@JsonSerialize(using = PrioritySerializer.class)
@Relation(collectionRelation = "priorities")
public enum Priority {
HIGH("High"),
NORMAL("Normal"),
LOW("Low");
private final String description;
Priority(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public static List<Priority> orderedValues = new ArrayList<>();
static {
orderedValues.addAll(Arrays.asList(Priority.values()));
}
}
@RepositoryRestController
@RequestMapping(value="/api")
public class PriorityController {
@GetMapping(value = "/priorities", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity<Resources<Priority>> getPriorities() {
Resources<Priority> resources = new Resources<>(Priority.orderedValues);
resources.add(linkTo(methodOn(PriorityController.class).getPriorities()).withSelfRel());
return ResponseEntity.ok(resources);
}
}
public class PrioritySerializer extends JsonSerializer<Priority> {
@Override
public void serialize(Priority priority,
JsonGenerator generator,
SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
generator.writeStartObject();
generator.writeFieldName("id");
generator.writeString(priority.name());
generator.writeFieldName("value");
generator.writeString(priority.getDescription());
generator.writeEndObject();
}
}
{
"_embedded": {
"priorities": [
{
"id": "HIGH",
"value": "High"
},
{
"id": "NORMAL",
"value": "Normal"
},
{
"id": "LOW",
"value": "Low"
}
]
},
"_links": {
"self": {
"href": "http://localhost:8080/api/priorities"
}
}
}