2017-06-29 128 views
1

我使用Spring Boot 1.5.3,Spring Data REST,HATEOAS。 我有一個簡單的實體模型:用Spring Data REST公開枚舉枚舉

@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(); 
} 
} 

我創建的角4.彈簧數據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.properties翻譯了我的枚舉值。大! 我的Angular頁面現在需要完整的角色列表(枚舉)。我有一些問題:

  • 瞭解更好的方式爲服務器返回的角色列表
  • 如何回報這份名單

我的第一個學嘗試是建立以一RepositoryRestController充分利用Spring Data REST提供的功能。

@RepositoryRestController 
@RequestMapping(path = "/api/v1") 

公共類UserController的{

@Autowired 
private EntityLinks entityLinks; 

@RequestMapping(method = RequestMethod.GET, path = "https://stackoverflow.com/users/roles", produces = "application/json") 
public Resource<Roles> findRoles() { 
    Resource<Roles> resource = new Resource<>(Roles.ROLE_ADMIN); 
    return resource; 
} 

不幸的是,由於某種原因,調用此方法返回一個404錯誤。我調試和資源創建正確,所以我想這個問題是在JSON轉換的某個地方。

回答

1

如何返回此列表?

@RepositoryRestController 
@RequestMapping("/roles") 
public class RoleController { 

    @GetMapping 
    public ResponseEntity<?> getAllRoles() { 
     List<Resource<Roles>> content = new ArrayList<>(); 
     content.addAll(Arrays.asList(
       new Resource<>(Roles.ROLE1 /*, Optional Links */), 
       new Resource<>(Roles.ROLE2 /*, Optional Links */))); 
     return ResponseEntity.ok(new Resources<>(content /*, Optional Links */)); 
    } 
} 
+0

它的工作最終JSON響應。但是,這是最好的做法嗎? – drenda

+0

在我看來,最好的方法是將你的角色從枚舉轉換爲實體。 – Cepr0

+0

我明白了,但似乎過分。遵循這個想法,每個枚舉將成爲一個枚舉......所以我不會看到枚舉點。相反,我認爲枚舉在這些情況下非常有用。 – drenda

0

我玩這個四周,發現一對夫婦的方式做到這一點。

假設您有一個前端表單,想要顯示包含單個待辦事項優先級的組合框,如High, Medium, Low。該表單需要知道primary key or id這是此實例中的枚舉值,並且該值應該是組合框應顯示的可讀格式值。

如果你想在1個地方定製json響應,例如單個端點,那麼我覺得這很有用。祕密調查使用值對象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); 
    } 

} 

另一種方法是使用自定義JsonSerializer。使用這個唯一的問題是無處不在的優先級枚舉序列化,你將最終使用這種格式,可能不是你想要的。

@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(); 
    } 
} 

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" 
     } 
    } 
}