目前,我通过使用@RepositoryRestResource注释它们来将一些Spring数据库公开为RESTful服务,如下所示:
@RepositoryRestResource(collectionResourceRel = "thing1", path = "thing1")
public interface Thing1Repository extends PagingAndSortingRepository<Thing1, String> {}
@RepositoryRestResource(collectionResourceRel = "thing2", path = "thing2")
public interface Thing2Repository extends CrudRepository<Thing2, String> {}
Run Code Online (Sandbox Code Playgroud)
一切都很好.当你点击我的第一个端点时,还会显示我公开的所有Spring Data Repositories,如下所示:
{
_links: {
thing1: {
href: "http://localhost:8080/thing1{?page,size,sort}",
templated: true
},
thing2: {
href: "http://localhost:8080/thing2"
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有一些我想公开的端点,这些端点无法由Spring Data Repositories表示,所以我使用的是RestController.
这是一个简单的例子:
@RestController
@ExposesResourceFor(Thing3.class)
@RequestMapping("/thing3")
public class Thing3Controller {
@Autowired
EntityLinks entityLinks;
@Autowired
Thing3DAO thing3DAO;
//just assume Thing3.class extends ResourceSupport. I know this is wrong, but it makes the example shorter …
Run Code Online (Sandbox Code Playgroud) 我有以下控制器方法:
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, value = "session/{id}/exercises")
public ResponseEntity<Resources<Exercise>> exercises(@PathVariable("id") Long id) {
Optional<Session> opt = sessionRepository.findWithExercises(id);
Set<Exercise> exercises = Sets.newLinkedHashSet();
if (opt.isPresent()) {
exercises.addAll(opt.get().getExercises());
}
Link link = entityLinks.linkFor(Session.class)
.slash(id)
.slash(Constants.Rels.EXERCISES)
.withSelfRel();
return ResponseEntity.ok(new Resources<>(exercises, link));
}
Run Code Online (Sandbox Code Playgroud)
所以基本上我试图揭露一个特定Set<>
的Exercise
实体Session
.当exercise实体为空时,我得到一个像这样的JSON表示:
{
"_links": {
"self": {
"href": "http://localhost:8080/api/sessions/2/exercises"
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上没有嵌入式实体,而以下类似的东西是可取的:
{
"_links": {
"self": {
"href": "http://localhost:8080/api/sessions/2/exercises"
}
},
"_embedded": {
"exercises": []
}
}
Run Code Online (Sandbox Code Playgroud)
任何想法如何执行这个?
我希望我的回复包括:
"keyMaps":{
"href":"http://localhost/api/keyMaps{/keyMapId}",
"templated":true
}
Run Code Online (Sandbox Code Playgroud)
这很容易实现:
add(new Link("http://localhost/api/keyMaps{/keyMapId}", "keyMaps"));
Run Code Online (Sandbox Code Playgroud)
但是,当然,我宁愿使用ControllerLinkBuilder,如下所示:
add(linkTo(methodOn(KeyMapController.class).getKeyMap("{keyMapId}")).withRel("keyMaps"));
Run Code Online (Sandbox Code Playgroud)
问题是,当变量"{keyMapId}"到达UriTemplate构造函数时,它已被包含在编码的URL中:
http://localhost/api/keyMaps/%7BkeyMapId%7D
Run Code Online (Sandbox Code Playgroud)
因此UriTemplate的构造函数不会将其识别为包含变量.
我如何说服我想使用模板变量的ControllerLinkBuilder?
我想为一个Employee
基本上是findByAllFields
查询的实体创建一个REST链接.当然这应该与Page
和结合使用Sort
.为此,我实现了以下代码:
@Entity
public class Employee extends Persistable<Long> {
@Column
private String firstName;
@Column
private String lastName;
@Column
private String age;
@Column
@Temporal(TemporalType.TIMESTAMP)
private Date hiringDate;
}
Run Code Online (Sandbox Code Playgroud)
所以我想让我们说一下我可以做的查询:
http://localhost:8080/myApp/employees/search/all?firstName=me&lastName=self&ageFrom=20&ageTo=30&hiringDateFrom=12234433235
Run Code Online (Sandbox Code Playgroud)
所以我有以下内容 Repository
@RepositoryRestResource(collectionResourceRel="employees", path="employees")
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long>,
JpaSpecificationExecutor<Employee> {
}
Run Code Online (Sandbox Code Playgroud)
好的,现在我需要一个RestController
@RepositoryRestController
public class EmployeeSearchController {
@Autowired
private EmployeeRepository employeRepository;
@RequestMapping(value = "/employees/search/all/search/all", method = RequestMethod.GET)
public Page<Employee> getEmployees(EmployeeCriteria filterCriteria, Pageable pageable) {
//EmployeeSpecification uses CriteriaAPI to form dynamic query with …
Run Code Online (Sandbox Code Playgroud) 我们可以HATEOAS
在上面使用弹簧RouterFunction
吗?我想我们可以指定资源但是相当于linkto(Controller.class)
什么?或是否有任何等效指定链接和使用组成RouterFunction
在Jackson
根据官方文档添加自定义序列化程序后,我观察到了略微不同的json输出格式.
这个例子是基于弹簧垫的叉子.
扩展org.springsource.restbucks.WebConfiguration
从RepositoryRestMvcConfiguration
并重写configureJacksonObjectMapper
:
@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
final SimpleSerializers serializers = new SimpleSerializers();
serializers.addSerializer(Order.class, new OrderSerializer());
objectMapper.registerModule(new SimpleModule("CustomSerializerModule"){
@Override public void setupModule(SetupContext context) {
context.addSerializers(serializers);
}
});
}
Run Code Online (Sandbox Code Playgroud)
创建类org.springsource.restbucks.order.OrderSerializer
.为简洁起见,只需将属性写paid
为JSON即可.
public class OrderSerializer extends JsonSerializer<Order> {
@Override
public void serialize(Order value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeBooleanField("paid", value.isPaid());
jgen.writeEndObject();
}
}
Run Code Online (Sandbox Code Playgroud)
在添加OrderSerializer json响应之前,http://localhost:8080/orders/1
看起来像:
{
"location": "TAKE_AWAY", …
Run Code Online (Sandbox Code Playgroud) 我有一个Spring Data Rest Repository控制器,它使用JPA进行查询实现,我需要添加一些使用JPA支持的标准queryByExample方法无法完成的自定义查询方法.我创建了一个具有必要方法的Impl类,但我不能让它被识别.我看到我可以使用标准的Spring MVC Controller,但我希望有一个统一的API,基本上我真正想要的是实现我自己的自定义/搜索方法.
即使使用自定义控制器,问题仍然是不再提供HAL链接和其他相关项目.
春天的人们可以花一些时间让某人记录如何做一些这些更高级的东西吗?我猜测,有时必须实现自己的搜索方法是相当普遍的,并且花费时间来明确如何做到这一点.
我曾经暴露了在实体中用@Id注释的主键.ID字段只在资源路径上可见,但在JSON主体上不可见.
我试图invoque非常简单的json webservices返回此表单的数据:
{
"_embedded": {
"users": [{
"identifier": "1",
"firstName": "John",
"lastName": "Doe",
"_links": {
"self": {
"href": "http://localhost:8080/test/users/1"
}
}
},
{
"identifier": "2",
"firstName": "Paul",
"lastName": "Smith",
"_links": {
"self": {
"href": "http://localhost:8080/test/users/2"
}
}
}]
},
"_links": {
"self": {
"href": "http://localhost:8080/test/users"
}
},
"page": {
"size": 20,
"totalElements": 2,
"totalPages": 1,
"number": 0
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它非常直接.解析链接没有问题,我的POJO从ResourceSupport扩展.这是他们的样子:
UsersJson(根元素)
public class UsersJson extends ResourceSupport {
private List<UserJson> users;
[... getters and setters ...]
}
Run Code Online (Sandbox Code Playgroud)
UserJson
public class UserJson …
Run Code Online (Sandbox Code Playgroud) 我正在关注Spring REST的教程,并试图将HATEOAS链接添加到我的Controller结果中.
我有一个简单的User类和一个CRUD控制器.
class User {
private int id;
private String name;
private LocalDate birthdate;
// and getters/setters
}
Run Code Online (Sandbox Code Playgroud)
服务:
@Component
class UserService {
private static List<User> users = new ArrayList<>();
List<User> findAll() {
return Collections.unmodifiableList(users);
}
public Optional<User> findById(int id) {
return users.stream().filter(u -> u.getId() == id).findFirst();
}
// and add and delete methods of course, but not important here
}
Run Code Online (Sandbox Code Playgroud)
一切正常,除了我的控制器,我想从所有用户列表添加链接到单个用户:
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public …
Run Code Online (Sandbox Code Playgroud) spring-hateoas ×10
spring ×8
java ×4
jackson ×2
spring-boot ×2
hypermedia ×1
json ×1
rest ×1
spring-data ×1