Spring获取实体的链接

问题描述 投票:0回答:3

我正在使用Spring-boot-starter-data-jpa,在我的RestController中我想返回新创建的对象的Location。有没有办法扭转@ RequestMapping而不是硬编码如何构建URL?

@RestController
@ExposesResourceFor(BookInstance.class)
public class BookInstanceController {
    @RequestMapping(value="/bookInstances", method=RequestMethod.POST)
    ResponseEntity<BookInstance> createBookInstance(@RequestBody BookInstance bookInstance){
    BookInstance createdBookInstance = bookInstanceRepository.save(bookInstance);

    return ResponseEntity.created(**reverseURL(createdBookInstance)**);
//      return new ResponseEntity<BookInstance>(createdBookInstance, HttpStatus.CREATED);
//      return createdBookInstance;
    }
}

我总是看到人们在这个函数中硬编码他们的URL构造,这让我没有言语......

当然我在同一个类中也有一个GET函数(否则就没有任何东西可以反转)

@RequestMapping(value="/bookInstances/{id}", method=RequestMethod.GET)
ResponseEntity<?> findOne(@PathVariable("id") Long id){
        BookInstance bookInstance = bookInstanceRepository.findOne(id);
        if(bookInstance == null){
            return ResponseEntity.notFound().build();
        }
        return new ResponseEntity<BookInstance>(bookInstance, HttpStatus.OK);
    }
spring spring-boot spring-data spring-data-rest spring-hateoas
3个回答
2
投票

使用资源汇编程序的替代解决方案:

public class BookInstanceResource extends Resource<BookInstance> {

    public BookInstanceResource(Book content, Link... links) {
        super(content, links);
    }

}

public class BookInstanceResourceAssembler extends ResourceAssemblerSupport<BookInstance, BookInstanceResource> {

    public BookInstanceResourceAssembler() {
        super(BookInstanceController.class, BookInstanceResource.class)
    }

    @Override
    public BookInstanceResource toResource(BookInstance bookInstance) {
        // linkTo requires the following static import:
        // import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
        ControllerLinkBuilder builder = linkTo(BookInstance.class).slash("bookInstances").slash(bookInstance);

        return new BookInstanceResource(bookInstance,
                                        builder.withSelfRel(),
                                        builder.withRel("bookInstance");
        }
}

在您的控制器类中:

@Autowired
private BookInstanceResourceAssembler resourceAssembler;

@GetMapping(value = "/bookInstances/{id}")
ResponseEntity findOne(@PathVariable("id") Long id) {
    BookInstance bookInstance = bookInstanceRepository.findOne(id);
    if(bookInstance == null){
        return ResponseEntity.notFound().build();
    }

    BookInstanceResource resource = resourceAssembler.toResource(bookInstance);

    return ResponseEntity.created(URI.create(resource.getLink("self").getHref()))
                         .body(resource);
}

2
投票

我把它添加到我的班级解决了它:

@Autowired EntityLinks entityLinks;

并使用Spring的一些HATEOAS功能。

Link link = entityLinks.linkToSingleResource(BookInstance.class, createdBookInstance.getId()).expand();
return ResponseEntity.created(URI.create(link.getHref())).build();

注意:在上面的行中,在创建DB中的记录后,createdBookInstance只是返回对象。


0
投票

由于其他解决方案与我的源代码不兼容,因此我很难找到返回新创建的实体访问API的URL的解决方案。我个人认为@EralpB解决方案很简单。但是,我遇到了SimpleEntityPlugin的一个问题,它在创建Link时在内部使用。

最后,我找到了简单代码剪切的解决方案,我不打算使用任何这样的Hateoas API。我不确定这个解决方案是否与Spring兼容,但我尝试使用SpringBoot-2.x版本。它对我来说很好。

@PostMapping("/students")
public ResponseEntity<Object> createStudent(@RequestBody Student student) {
    Student savedStudent = studentRepository.save(student);
    URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
        .buildAndExpand(savedStudent.getId()).toUri();
    return ResponseEntity.created(location).build();
}

根据上面的例子,URL将像http://localhost:8080/students/1一样返回。这可能会因您的配置而异。

如果您需要在学生旁边和URL中的id之前添加任何额外路径,您可以直接在{id}声明之前进行硬编码,例如/ search / {id}。所以实际的URL看起来像http://localhost:8080/students/search/1

如果以防万一,您没有将学生配置为按ID搜索学生的一部分,并且您配置了一些其他路径来按ID访问学生,您可以使用以下代码仅加载上下文,路径例如http://localhost:8080并添加硬编码/加载属于uri。

URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/search/{id}")
                .buildAndExpand(newCase.getCaseId()).toUri();

根据上面的代码片段,返回的URL看起来像http://localhost:8080/search/1。您可以探索ServletUriComponentsBuilder下的不同方法。我希望这一点很清楚。

© www.soinside.com 2019 - 2024. All rights reserved.