Spring Data REST: 在控制器上重新定义存储库方法

我有以下存储库 REST, 执行在执行期间生成 Spring.


@RepositoryRestResource
public interface FooRepository extends CrudRepository<foo, long=""> {

}


这意味着我会有 save//, find//, exists// 和其他方法可用和开放 REST.

现在我想覆盖其中一个方法; 例如, save//. 为此,我会创建一个提供此方法的控制器,例如:


@RepositoryRestController
@RequestMapping/"/foo"/
public class FooController {

@Autowired
FooService fooService;


@RequestMapping/value = "/{fooId}", method = RequestMethod.PUT/
public void updateFoo/@PathVariable Long fooId/ {
fooService.updateProperly/fooId/;
}

}


问题:

如果我打开这个控制器,那么实现所有其他方法 Spring, 不再可用。 因此,例如,我再也不能提出请求 GET 在 /foo/1

问题:

有没有办法覆盖方法 REST, 同时保持其他自动生成的方法 Spring?

附加信息

:

这个问题似乎非常相似:
https://coderoad.ru/28455208/
..., 但我不想改变这样的方式 /foo/1/save

我想使用 @RepositoryEventHandler, 但我并不像这个想法,因为我想把它封装在服务中。 此外,您似乎对交易的背景失去了控制。

http://docs.spring.io/spring-d ... dlers
Spring 以下说:

有时您可能需要为特定的定制处理程序编写自定义处理程序
资源。 利用设置 Spring Data REST,
消息转换器,异常处理和可用力,使用
注解 @RepositoryRestController 而不是标准 Spring MVC
@Controller 或者 @RestController


所以它似乎应该开箱即用,但不幸的是,没有。
</foo,>
已邀请:

三叔

赞同来自:

有没有办法覆盖方法 REST, 同时保持其他自动生成的方法 Spring?

仔细研究文档中的示例:虽然它显然不禁止比较类级查询,但它使用方法级别的请求比较。
我不确定这是否是所需的行为或错误,但据我所知,这是使其工作的唯一方法
https://jira.spring.io/browse/DATAREST-535
.

只需将控制器更改为:


@RepositoryRestController
public class FooController {

@Autowired
FooService fooService;

@RequestMapping/value = "/foo/{fooId}", method = RequestMethod.PUT/
public void updateFoo/@PathVariable Long fooId/ {
fooService.updateProperly/fooId/;
}

// edited after Sergey's comment
@RequestMapping/value = "/foo/{fooId}", method = RequestMethod.PUT/
public RequestEntity<void> updateFoo/@PathVariable Long fooId/ {
fooService.updateProperly/fooId/;

return ResponseEntity.ok//.build//; // simplest use of a ResponseEntity
}
}


</void>

龙天

赞同来自:

让我们想象我们有本质
Account

:


@Entity
public class Account implements Identifiable<integer>, Serializable {

private static final long serialVersionUID = -3187480027431265380L;

@Id
private Integer id;
private String name;

public Account/Integer id, String name/ {
this.id = id;
this.name = name;
}

public void setId/Integer id/ {
this.id = id;
}

@Override
public Integer getId// {
return id;
}

public String getName// {
return name;
}

public void setName/String name/ {
this.name = name;
}
}



AccountRepository

, 展示腰带 CRUD 结束点
/accounts

:


@RepositoryRestResource/collectionResourceRel = "accounts", path = "accounts"/
public interface AccountRepository extends CrudRepository<account, integer=""> {
}



AccountController

, 哪个覆盖终点形状
GET

默认
AccountRepository

.:


@RepositoryRestController
public class AccountController {
private PagedResourcesAssembler<account> pagedAssembler;

@Autowired
public AccountController/PagedResourcesAssembler<account> pagedAssembler/ {
this.pagedAssembler = pagedAssembler;
}

private Page<account> getAccounts/Pageable pageRequest/{
int totalAccounts= 50;
List<account> accountList = IntStream.rangeClosed/1, totalAccounts/
.boxed//
.map/ value -&gt; new Account/value, value.toString////
.skip/pageRequest.getOffset///
.limit/pageRequest.getPageSize///
.collect/Collectors.toList///;
return new PageImpl/accountList, pageRequest, totalAccounts/;
}

@RequestMapping/method= RequestMethod.GET, path="/accounts", produces = "application/hal+json"/
public ResponseEntity<page<account>&gt; getAccountsHal/Pageable pageRequest, PersistentEntityResourceAssembler assembler/{
return new ResponseEntity/pagedAssembler.toResource/getAccounts/pageRequest/, /ResourceAssembler/ assembler/, HttpStatus.OK/;
}


如果你打电话
GET /accounts?size=5&amp;page=0

, 您将获得以下输出,该输出使用实现布局:


{
"_embedded": {
"accounts": [
{
"name": "1",
"_links": {
"self": {
"href": "[url=http://localhost:8080/accounts/1"]http://localhost:8080/accounts/1"[/url]
},
"account": {
"href": "[url=http://localhost:8080/accounts/1"]http://localhost:8080/accounts/1"[/url]
}
}
},
{
"name": "2",
"_links": {
"self": {
"href": "[url=http://localhost:8080/accounts/2"]http://localhost:8080/accounts/2"[/url]
},
"account": {
"href": "[url=http://localhost:8080/accounts/2"]http://localhost:8080/accounts/2"[/url]
}
}
},
{
"name": "3",
"_links": {
"self": {
"href": "[url=http://localhost:8080/accounts/3"]http://localhost:8080/accounts/3"[/url]
},
"account": {
"href": "[url=http://localhost:8080/accounts/3"]http://localhost:8080/accounts/3"[/url]
}
}
},
{
"name": "4",
"_links": {
"self": {
"href": "[url=http://localhost:8080/accounts/4"]http://localhost:8080/accounts/4"[/url]
},
"account": {
"href": "[url=http://localhost:8080/accounts/4"]http://localhost:8080/accounts/4"[/url]
}
}
},
{
"name": "5",
"_links": {
"self": {
"href": "[url=http://localhost:8080/accounts/5"]http://localhost:8080/accounts/5"[/url]
},
"account": {
"href": "[url=http://localhost:8080/accounts/5"]http://localhost:8080/accounts/5"[/url]
}
}
}
]
},
"_links": {
"first": {
"href": "[url=http://localhost:8080/accounts?page=0&amp;size=5"]http://localhost:8080/accounts ... ot%3B[/url]
},
"self": {
"href": "[url=http://localhost:8080/accounts?page=0&amp;size=5"]http://localhost:8080/accounts ... ot%3B[/url]
},
"next": {
"href": "[url=http://localhost:8080/accounts?page=1&amp;size=5"]http://localhost:8080/accounts ... ot%3B[/url]
},
"last": {
"href": "[url=http://localhost:8080/accounts?page=9&amp;size=5"]http://localhost:8080/accounts ... ot%3B[/url]
}
},
"page": {
"size": 5,
"totalElements": 50,
"totalPages": 10,
"number": 0
}
}


只是为了完整的图片 POM 它可以配置为以下父级和依赖项:


<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.data</groupid>
<artifactid>spring-data-rest-webmvc</artifactid>
<version>2.6.1.RELEASE</version>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-jpa</artifactid>
</dependency>
<dependency>
<groupid>com.h2database</groupid>
<artifactid>h2</artifactid>
</dependency>
</dependencies>


</page<account></account></account></account></account></account,></integer>

窦买办

赞同来自:

只是我找到的更新,救了我的生活。
辉煌地说 @mathias-dpunkt 在这个答案中

最重要的是 RepositoryRestController 知道O. spring 数据 rest
基本路径,将根据这种基本方式提供服务。

所以,如果你的基本方式 "/api " 你使用 @RepositoryRestController

你必须省略 "/api " 的 @RequestMapping

莫问

赞同来自:

如果你使用,我发现了一个整洁的决定 Java 8 - 只需使用界面中的默认方法。


@RepositoryRestResource
public interface FooRepository extends CrudRepository<foo, long=""> {
default <s extends="" t=""> S save/S var1/ {
//do some work here
}
}


</s></foo,>

要回复问题请先登录注册