混合Spring MVC + Spring Data Rest会产生奇怪的MVC响应

bvu*_*laj 15 java spring-mvc spring-data spring-data-rest spring-boot

我有两个JPA实体,一个带有SDR导出的存储库,另一个带有Spring MVC控制器,还有一个非导出的存储库.

MVC公开实体具有对SDR管理实体的引用.请参阅下面的代码参考.

User从中检索a时,问题就出现了UserController.SDR管理的实体不会序列化,而且似乎Spring可能正在尝试在响应中使用HATEOAS引用.

这是GET一个完全填充的User外观:

{
  "username": "foo@gmail.com",
  "enabled": true,
  "roles": [
    {
      "role": "ROLE_USER",
      "content": [],
      "links": [] // why the content and links?
    }
    // no places?
  ]
}
Run Code Online (Sandbox Code Playgroud)

如何User通过嵌入式SDR管理实体从Controller中清楚地返回实体?

Spring MVC管理

实体

@Entity
@Table(name = "users")
public class User implements Serializable {

    // UID

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Long id;

    @Column(unique = true)
    @NotNull
    private String username;

    @Column(name = "password_hash")
    @JsonIgnore
    @NotNull
    private String passwordHash;

    @NotNull
    private Boolean enabled;

    // No Repository
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    @NotEmpty
    private Set<UserRole> roles = new HashSet<>();

    // The SDR Managed Entity
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_place", 
        joinColumns = { @JoinColumn(name = "users_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "place_id")})
    private Set<Place> places = new HashSet<>();

    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)

回购

@RepositoryRestResource(exported = false)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
    // Query Methods
}
Run Code Online (Sandbox Code Playgroud)

调节器

@RestController
public class UserController {

    // backed by UserRepository
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(path = "/users/{username}", method = RequestMethod.GET)
    public User getUser(@PathVariable String username) {
        return userService.getByUsername(username);
    }

    @RequestMapping(path = "/users", method = RequestMethod.POST)
    public User createUser(@Valid @RequestBody UserCreateView user) {
        return userService.create(user);
    }

    // Other MVC Methods
}
Run Code Online (Sandbox Code Playgroud)

SDR管理

实体

@Entity
public class Place implements Serializable {

    // UID

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotBlank
    private String name;

    @Column(unique = true)
    private String handle;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "address_id")
    private Address address;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "contact_info_id")
    private ContactInfo contactInfo;

    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)

回购

public interface PlaceRepository extends PagingAndSortingRepository<Place, Long> {
    // Query Methods
}
Run Code Online (Sandbox Code Playgroud)

sha*_*h15 -1

您可以很好地在控制器中使用@ResponseEntity,然后在ResponseEntity中设置用户对象。

请参阅下面的示例:

ResponseEntity<User> respEntity = new ResponseEntity<User>(user, HttpStatus.OK);
Run Code Online (Sandbox Code Playgroud)

然后在客户端你可以调用,restTemplate.getForEntity

请参阅下面的restTemplate文档:

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.String-java.lang.Class-java.lang。目的...-