Spring Boot:使用 RestTemplate 调用查询
SpringBoot: call a query using RestTemplate
我刚开始使用 Spring Boot,我想使用 RestTemplate 来调用查询和 return 它的结果。
@Repository
public interface ApplicantRepository extends CrudRepository<Applicant, Integer> {
@Query("SELECT a FROM Applicant a WHERE a.propertyTypeId = :typeId" +
" AND a.bedrooms = :bedrooms" +
" AND a.budget = :price")
List<Applicant> findByMatchingCriteria(@Param("typeId")int typeId, @Param("bedrooms") int bedrooms,
@Param("price") int price);
}
我正在调用此 RestController 中的查询 "findByMatchingCriteria":
@RestController
public class MatchingController {
private RestTemplate restTemplate = new RestTemplate();
@RequestMapping(method = GET, value = "matchingByProperty/{propertyId}")
public List matchingByProperty(@PathVariable int propertyId) {
Property property = restTemplate.getForObject("http://localhost:8080/api/properties/" + propertyId, Property.class);
return restTemplate.getForObject("http://localhost:8080/api/applicants/search/findByMatchingCriteria?typeId=" + property.getTypeId()
+ "&bedrooms=" + property.getBedrooms()
+ "&price=" + property.getPrice(), List.class);
}
}
属性 看起来像这样:
@Entity
public class Property {
private @Id @GeneratedValue int id;
private String fullAddress;
private int typeId;
private int subtypeId;
private int bedrooms;
private int price;
private Property() {}
public Property(String fullAddress, int typeId, int subtypeId, int bedrooms, int price) {
this.fullAddress = fullAddress;
this.typeId = typeId;
this.subtypeId = subtypeId;
this.bedrooms = bedrooms;
this.price = price;
}
// getters and setters
}
当我测试 "matchingByProperty/{propertyId}" url 时,出现以下错误:
exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@3bd79387; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@3bd79387; line: 1, column: 1]
如何使用 RestTemplate 调用查询?或者有更好的方法吗?
如果您只想从控制器调用您自己的存储库,则无需使用 RestTemplate
通过 HTTP。只需将存储库注入您的控制器,然后调用方法:
@RestController
public class MatchingController {
@Autowired
private ApplicantRepository applicantRepository;
@RequestMapping(method = GET, value = "matchingByProperty/{propertyId}")
public List matchingByProperty(@PathVariable int propertyId) {
// You probably should not be going over HTTP for this either
// and autowiring a property repository.
Property property = restTemplate.
getForObject("http://localhost:8080/api/properties/" + propertyId, Property.class);
return applicantRepository.findByMatchingCriteria(property.getTypeId(), property.getBedrooms(), property.getPrice());
}
}
如果您出于某种原因确实想通过 HTTP,您可以使用此处找到的方法:Get list of JSON objects with Spring RestTemplate
想出了解决我的问题的方法。
在调用 ApplicantRepository 查询的 ApplicantController 中创建了一个 REST 方法:
@RequestMapping(method = POST, value = "/api/applicants/getMatchedApplicants")
public List getMatchedApplicants(@RequestBody HashMap property) {
List<Applicant> applicants = applicantRepository.matchedApplicants((int) property.get("typeId"),
(int) property.get("bedrooms"),
(int) property.get("price"));
return applicants == null ? new ArrayList() : applicants;
}
然后MatchingController通过REST调用ApplicantController中的方法
这就是我想要的,两个不同的服务(匹配和申请人)通过 REST 进行通信。
谢谢@Adam,你的建议对我很有帮助。
我刚开始使用 Spring Boot,我想使用 RestTemplate 来调用查询和 return 它的结果。
@Repository
public interface ApplicantRepository extends CrudRepository<Applicant, Integer> {
@Query("SELECT a FROM Applicant a WHERE a.propertyTypeId = :typeId" +
" AND a.bedrooms = :bedrooms" +
" AND a.budget = :price")
List<Applicant> findByMatchingCriteria(@Param("typeId")int typeId, @Param("bedrooms") int bedrooms,
@Param("price") int price);
}
我正在调用此 RestController 中的查询 "findByMatchingCriteria":
@RestController
public class MatchingController {
private RestTemplate restTemplate = new RestTemplate();
@RequestMapping(method = GET, value = "matchingByProperty/{propertyId}")
public List matchingByProperty(@PathVariable int propertyId) {
Property property = restTemplate.getForObject("http://localhost:8080/api/properties/" + propertyId, Property.class);
return restTemplate.getForObject("http://localhost:8080/api/applicants/search/findByMatchingCriteria?typeId=" + property.getTypeId()
+ "&bedrooms=" + property.getBedrooms()
+ "&price=" + property.getPrice(), List.class);
}
}
属性 看起来像这样:
@Entity
public class Property {
private @Id @GeneratedValue int id;
private String fullAddress;
private int typeId;
private int subtypeId;
private int bedrooms;
private int price;
private Property() {}
public Property(String fullAddress, int typeId, int subtypeId, int bedrooms, int price) {
this.fullAddress = fullAddress;
this.typeId = typeId;
this.subtypeId = subtypeId;
this.bedrooms = bedrooms;
this.price = price;
}
// getters and setters
}
当我测试 "matchingByProperty/{propertyId}" url 时,出现以下错误:
exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@3bd79387; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@3bd79387; line: 1, column: 1]
如何使用 RestTemplate 调用查询?或者有更好的方法吗?
如果您只想从控制器调用您自己的存储库,则无需使用 RestTemplate
通过 HTTP。只需将存储库注入您的控制器,然后调用方法:
@RestController
public class MatchingController {
@Autowired
private ApplicantRepository applicantRepository;
@RequestMapping(method = GET, value = "matchingByProperty/{propertyId}")
public List matchingByProperty(@PathVariable int propertyId) {
// You probably should not be going over HTTP for this either
// and autowiring a property repository.
Property property = restTemplate.
getForObject("http://localhost:8080/api/properties/" + propertyId, Property.class);
return applicantRepository.findByMatchingCriteria(property.getTypeId(), property.getBedrooms(), property.getPrice());
}
}
如果您出于某种原因确实想通过 HTTP,您可以使用此处找到的方法:Get list of JSON objects with Spring RestTemplate
想出了解决我的问题的方法。
在调用 ApplicantRepository 查询的 ApplicantController 中创建了一个 REST 方法:
@RequestMapping(method = POST, value = "/api/applicants/getMatchedApplicants")
public List getMatchedApplicants(@RequestBody HashMap property) {
List<Applicant> applicants = applicantRepository.matchedApplicants((int) property.get("typeId"),
(int) property.get("bedrooms"),
(int) property.get("price"));
return applicants == null ? new ArrayList() : applicants;
}
然后MatchingController通过REST调用ApplicantController中的方法
这就是我想要的,两个不同的服务(匹配和申请人)通过 REST 进行通信。
谢谢@Adam,你的建议对我很有帮助。