我有一个Spring Data Rest Repository控制器,它使用JPA进行查询实现,我需要添加一些使用JPA支持的标准queryByExample方法无法完成的自定义查询方法.我创建了一个具有必要方法的Impl类,但我不能让它被识别.我看到我可以使用标准的Spring MVC Controller,但我希望有一个统一的API,基本上我真正想要的是实现我自己的自定义/搜索方法.
即使使用自定义控制器,问题仍然是不再提供HAL链接和其他相关项目.
春天的人们可以花一些时间让某人记录如何做一些这些更高级的东西吗?我猜测,有时必须实现自己的搜索方法是相当普遍的,并且花费时间来明确如何做到这一点.
我正在关注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) 使用带有methodOn功能的ControllerLinkBuilder时,我不明白的一件事是当你的Controller有这样的方法签名时你应该怎么做:
public HttpEntity<ResourceSupport> update(@PathVariable(USER_ID) Long userId, @Valid @RequestBody UserUpdateRequest userUpdateRequest, BindingResult bindingResult)
Run Code Online (Sandbox Code Playgroud)
所以每当我想使用methodOn,我怎样填补像空白UserUpdateRequest参数和BindingResult(我用结合的结果来处理与@ControllerAdvice和JSR 303错误的请求异常,使输出消息人类可读).
当我想利用开箱春天HATEOAS的ControllerLinkBuilder更多的方便与methodOn我写出来这样的事情(介意我,我不知道这是否会事与愿违但代码看起来不舒服):
resource.add(linkTo(methodOn(UserController.class).update(userId, null, null)).withSelfRel());
Run Code Online (Sandbox Code Playgroud)
Ofcourse我可以省略methodOn一部分,只是使用linkTo那么这就需要我玩围绕建设路径.
传递null refs 是否合适?加上使用它是如何方便methodOn:因为如果你决定要删除的发言权BindingResult或添加类似的HttpServletRequest控制器方法签名,这样弹簧可以传递我关于请求的详细信息,如果我想为一些安全原因登录的IP地址.这将要求我使用methodOn更改链接构造部分.
是位难以置信我还有一个问题是说,我通过一个合法的裁判methodOn像userUpdateRequest充满了数据-这是否想与生成的链接去任何地方的数据?我已经看到一些超媒体包含rel和href你传递的内容 - 是否可以使用Spring HATEOAS,这是一个很好的做法,创建链接,准备发布/放置有效负载?
但是,仅使用linkTo方法建立与.slash("...")链接的方法回到ControllerLinkBuilder,是否可能降低维护成本?
在日常实践中你会推荐什么,你对链接构建有什么看法?也许有人可以提供专业的提示/建议.
谢谢,
是否有任何插件(类似于Swagger)提供了记录HATEOAS API的能力?
Swagger界面相当不错,但它没有3级REST支持.
我正在尝试使用spring-boot-starter-data-rest使用Spring Boot构建RESTful API.有一些实体:帐户,交易,类别和用户 - 只是通常的东西.
当我通过默认生成的API 检索http:// localhost:8080/transactions中的对象时,一切顺利,我得到一个包含所有事务的列表作为JSON对象,如下所示:
{
"amount": -4.81,
"date": "2014-06-17T21:18:00.000+0000",
"description": "Pizza",
"_links": {
"self": {
"href": "http://localhost:8080/transactions/5"
},
"category": {
"href": "http://localhost:8080/transactions/5/category"
},
"account": {
"href": "http://localhost:8080/transactions/5/account"
}
}
}
Run Code Online (Sandbox Code Playgroud)
但现在的目标是仅检索该URL下的最新事务,因为我不想序列化整个数据库表.所以我写了一个控制器:
@Controller
public class TransactionController {
private final TransactionRepository transactionRepository;
@Autowired
public TransactionController(TransactionRepository transactionRepository) {
this.transactionRepository = transactionRepository;
}
// return the 5 latest transactions
@RequestMapping(value = "/transactions", method = RequestMethod.GET)
public @ResponseBody List<Transaction> getLastTransactions() {
return transactionRepository.findAll(new PageRequest(0, 5, new Sort(new Sort.Order(Sort.Direction.DESC, "date")))).getContent(); …
Run Code Online (Sandbox Code Playgroud) spring spring-mvc spring-data-rest spring-hateoas spring-boot
我正在尝试使用Spring Boot的Spring HATEOAS.我小心翼翼地写了一个单元测试:
given().standaloneSetup(new GreetingApi())
.accept("application/hal+json;charset=UTF-8")
.when()
.get("/greeting")
.prettyPeek()
.then().statusCode(200)
.body("content", equalTo("Hello, World"))
.body("_links.self.href", endsWith("/greeting?name=World"));
Run Code Online (Sandbox Code Playgroud)
测试返回响应如下:
Content-Type: application/hal+json;charset=UTF-8
{
"content": "Hello, World",
"links": [
{
"rel": "self",
"href": "http://localhost/greeting?name=World"
}
]
}
Run Code Online (Sandbox Code Playgroud)
但实际上,当我运行整个Spring Boot应用程序时,响应会像这样:
HTTP/1.1 200
Content-Type: application/hal+json;charset=UTF-8
Date: Wed, 24 May 2017 15:28:39 GMT
Transfer-Encoding: chunked
{
"_links": {
"self": {
"href": "http://localhost:8080/greeting?name=World"
}
},
"content": "Hello, World"
}
Run Code Online (Sandbox Code Playgroud)
所以必须有一些方法来配置HATEOAS的响应,但我没有找到它.
希望熟悉此事的人可以帮助我.
整个存储库都在这里.
我有一个REST服务,我想为我的客户开发团队记录.
所以我加了一些Links
从Spring-Hateoas
我的资源API,并插入到它swagger-springmvc
@Api...
注解来记录一切,使一个很好的API参考我的角团队能够理解我的REST服务.
问题是swagger
无法发现可能的链接,只是给我一大堆Links
而不说他们可能的价值观.
这是一个(简单)的例子.Swagger检测到:
Model Schema
CollectionListResource {
collections (array[CollectionResource]): All available collections,
links (array[Link]): Relations for next actions
}
CollectionResource {
collectionId (string): Collection Unique Id,
name (string): Human readable collection name,
links (array[Link]): Relations for next actions
}
Link {
rel (string, optional),
templated (boolean, optional),
href (string, optional)
}
Run Code Online (Sandbox Code Playgroud)
我实际上在HAL中:
{"collections":
[{"collectionId":"5370a206b399c65f05a7c59e",
"name":"default",
"_links":{ [
"self":{
"href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
},
"delete":{
"href":"http://localhost:9080/collections/5370a206b399c65f05a7c59e"
}
]}
}, ...]}
Run Code Online (Sandbox Code Playgroud)
我试图扩展Link …
正如标题所说,我有一个资源对象Product
扩展ResourceSupport
.但是,我收到的回复具有属性"_links"而不是"links",并且具有不同的结构.
{
"productId" : 1,
"name" : "2",
"_links" : {
"self" : {
"href" : "http://localhost:8080/products/1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
基于HATEOAS参考,预期是:
{
"productId" : 1,
"name" : "2",
"links" : [
{
"rel" : "self"
"href" : "http://localhost:8080/products/1"
}
]
}
Run Code Online (Sandbox Code Playgroud)
这是有意的吗?有没有办法改变它,或者如果不是结构那么就是"链接"?
我通过以下代码段添加了selfLink:
product.add(linkTo(ProductController.class).slash(product.getProductId()).withSelfRel());
Run Code Online (Sandbox Code Playgroud)
我使用以下构建文件的spring boot:
dependencies {
compile ("org.springframework.boot:spring-boot-starter-data-rest") {
exclude module: "spring-boot-starter-tomcat"
}
compile "org.springframework.boot:spring-boot-starter-data-jpa"
compile "org.springframework.boot:spring-boot-starter-jetty"
compile "org.springframework.boot:spring-boot-starter-actuator"
runtime "org.hsqldb:hsqldb:2.3.2"
testCompile "junit:junit"
}
Run Code Online (Sandbox Code Playgroud) 我有许多使用Spring Boot构建的微服务,所以为了一点乐趣,我想我会为他们添加HATEOAS以帮助建立跨资源链接.它似乎在一个特定的项目中工作得很好,但我想知道是否有一种很好的方式来链接API.举个例子,假设我有3个服务:
用户详细信息服务:代码:
/users/{userid}
Run Code Online (Sandbox Code Playgroud)
用户日历服务:代码:
/users/{userid}/appointments
/users/{userid}/appointments/{appointmentid}
Run Code Online (Sandbox Code Playgroud)
用户消息服务:代码:
/users/{userid}/messages
/users/{userid}/messages/{messageid}
Run Code Online (Sandbox Code Playgroud)
为了通过API实现这一点,最好是从用户资源到其约会和消息的链接.同样,从这些资源返回链接会很不错.当我有一个包含类路径上的所有内容的API时,这是非常可行的,我可以编写如下代码:
码:
user.add(linkTo(methodOn(CalendarController.class).appointments(user.getKey())).withRel("appointments"))
Run Code Online (Sandbox Code Playgroud)
但是,如果CalendarController不在我正在服务的服务的类路径上,我就无法做到这一点.
有没有一个好的/推荐的方法来创建不在当前项目中的控制器的链接?
从春季论坛引用
我正在使用带有 HATEOAS 和 Gradle 的 Spring Boot 2.2.0.M1。
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
Run Code Online (Sandbox Code Playgroud)
目前,Resource
IDE (IntelliJ IDEA 2018.3) 未找到,并ControllerLinkBuilder
标记为deprecated。
package com.example.restfulwebservicegradle.user;
import static org.springframework.hateoas.server.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import com.example.restfulwebservicegradle.User;
import com.example.restfulwebservicegradle.UserDaoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.server.mvc.ControllerLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import javax.validation.Valid;
import java.net.URI;
import java.util.List;
@RestController
public class UserResource {
@Autowired
private UserDaoService service;
@GetMapping("users/{id}")
public Resource<User> retrieveUser(@PathVariable int id) {
User user = service.findOne(id);
if (user == null)
throw new UserNotFoundException("id-" + id);
// Resource …
Run Code Online (Sandbox Code Playgroud) spring-hateoas ×10
spring ×7
spring-boot ×6
java ×4
spring-mvc ×4
hateoas ×2
api ×1
rest ×1
swagger ×1