我在 spring-boot-starter-data-rest 中使用 Spring boot 1.5.10 。
我创建了域实体:
@Entity
public class User {
@Column
private long id;
@Column
private String firstName;
@Column
private String secondName;
@Column
private int age;
@Fetch(FetchMode.SELECT)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
private Address address;
...
}
@Entity
public class Address {
@Column
private long id;
@Column
private String city;
@Column
private String street;
@Column
private String build;
...
}
我已经为这个域实体创建了存储库:
interface UserRepository extends JpaRepository<User, String> {
User getUserByFirstNameAndSecondName(String firstName, String secondName);
@RestResource(exported = false)
User getUserByAddress(Address address);
}
interface AddressRepository extends JpaRepository<Address, String> {
Address getAddressByStreet(String street);
}
之后我给下一个HATEOAS根端点:
{
"_links" : {
"users" : {
"href" : "http://localhost:8080/api/v1/users{?page,size,sort}",
"templated" : true
},
"address" : {
"href" : "http://localhost:8080/api/v1/address{?page,size,sort}",
"templated" : true
}
}
如果我导航到http://localhost:8080/api/v1/users,我会得到类似的内容:
{
"_links" : {
"getUserByFirstNameAndSecondName" : {
"href" : "http://localhost:8080/api/v1/users/search/getUserByFirstNameAndSecondName{?firstName, secondName ,projection}",
"templated" : true
},
"self" : {
"href" : "http://localhost:8081/api/v1/users/search"
}
}
}
但我想在&#34; http://localhost:8080/api/v1/users/search&#34;添加新的端点。使用自定义控制器,使用 @RepositoryRestController ,例如:
@RepositoryRestController
public class UserRestController {
private UserRepository userRepository;
@Autowired
public UserRestController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@RequestMapping("/users/search/getUserByStreetAddress")
public User getUserByStreetAddress(String street) {
Address address = new Address();
address.setStreet(street);
return userRepository.getUserByAddress(address);
}
}
但是我的控制器没有向现有端点添加任何内容。 我已阅读How to add links to root resource in Spring Data REST?,此决定适用于根端点,但我想将 getUserByStreetAddress 端点添加到用户/搜索,最终获得以下内容:< / p>
{
"_links" : {
"getUserByFirstNameAndSecondName" : {
"href" : "http://localhost:8080/api/v1/users/search/getUserByFirstNameAndSecondName{?firstName, secondName ,projection}",
"templated" : true
},
//Method from my custom controller added to http://localhost:8080/api/v1/users/search" endpoint
"getUserByStreetAddress" : {
"href" : "http://localhost:8080/api/v1/users/search/getUserByStreetAddress{?street ,projection}",
"templated" : true
},
"self" : {
"href" : "http://localhost:8080/api/v1/users/search"
}
}
}
是否可以这样做?
答案 0 :(得分:2)
您需要实施ResourceProcessor<RepositorySearchesResource>
并手动添加链接。
// other imports here
import static org.springframework.hateoas.TemplateVariable.VariableType.REQUEST_PARAM;
@Component
public class RepositorySearchesResourceProcessor implements ResourceProcessor<RepositorySearchesResource> {
@Autowired
private RepositoryRestConfiguration restConfiguration;
@Override
public RepositorySearchesResource process(RepositorySearchesResource resource) {
// early exit if we're not dealing with a User resource
if (!User.class.equals(resource.getDomainType())) {
return resource;
}
// add a custom link to /users/search
String search = resource.getId().getHref();
List<TemplateVariable> list = new ArrayList<>;
list.add(new TemplateVariable("street", REQUEST_PARAM);
boolean addProjection = restConfiguration.getProjectionConfiguration().hasProjectionFor(Parameter.class);
if (addProjection) {
// should be "projection" unless you configured it differently
list.add(restConfiguration.getProjectionConfiguration().getParameterName());
}
TemplateVariables tvs = new TemplateVariables(list);
Link link = new Link(new UriTemplate(search + "/getUserByStreetAddress", tvs"), "getUserByStreetAddress");
resource.add(link);
return resource;
}
我放入RepositoryRestConfiguration和UriTemplate,以便稍后在必要时提供关于添加其他休息参数(分页,排序......)的提示。