Java 如何将文本响应绑定到json并在micronaut上的声明性客户端上放入对象?
我在micronaut内置的应用程序上创建了声明式http客户端。这需要使用一个以text/html类型响应的服务 我设法得到一个列表,但里面有Java 如何将文本响应绑定到json并在micronaut上的声明性客户端上放入对象?,java,http,micronaut,Java,Http,Micronaut,我在micronaut内置的应用程序上创建了声明式http客户端。这需要使用一个以text/html类型响应的服务 我设法得到一个列表,但里面有LinkedHashMap。我希望它们成为药店的对象 我的问题是:如何将响应转换为对象列表 @Client("${services.url}") public interface PharmacyClient { @Get("${services.path}?${services.param}=${services.
LinkedHashMap
。我希望它们成为药店的对象
我的问题是:如何将响应转换为对象列表
@Client("${services.url}")
public interface PharmacyClient {
@Get("${services.path}?${services.param}=${services.value}")
Flowable<List<Pharmacy>> retrieve();
}
@Client(${services.url})
公共接口药剂师{
@获取(${services.path}?${services.param}=${services.value}”)
可流动检索();
}
公共类存储服务{
私人最终制药公司;
公共商店服务(PharmacyClient PharmacyClient){
这是。Pharmacycient=Pharmacycient;
}
公共可流动全部(){
Flowable listFlowable=this.pharmacyClient.retrieve();
返回列表可流动
.doError(throwable->log.error(throwable.getLocalizedMessage()))
.flatMap(药房->
Flowable.just(pharmacies.stream()//这是LinkedHashMap的列表,我想使用Pharmacy对象
.map(药房->商店.builder().borough(药房.getBoroughFk()).build())
.collect(收集器.toList())
)
);
}
}
代码:没有一个成熟的框架AFAIK像Micronaut那样为HTML内容到
POJO
映射(通常是在废弃中创造的)提供支持
同时,您可以基于截取和转换API结果,轻松地插入转换器bean,并将其转换为等效的POJO:
class Root {
@Selector(value = ".pharmacy") List<Pharmacy> pharmacies;
}
class Pharmacy {
@Selector(value = "span:nth-child(1)") String name;
}
@Client("${services.minsal.url}")
public interface PharmacyClient {
@Get("${services.minsal.path}?${services.minsal.param}=${services.minsal.value}")
Flowable<String> retrieve();
}
@Singleton
public class ConverterService {
public List<Pharmacy> toPharmacies(String htmlContent) {
Jspoon jspoon = Jspoon.create();
HtmlAdapter<Root> htmlAdapter = jspoon.adapter(Root.class);
return htmlAdapter.fromHtml(htmlContent).pharmacies;
}
}
public class StoreService {
private final PharmacyClient pharmacyClient;
private final ConverterService converterService;
public StoreService(PharmacyClient pharmacyClient, ConverterService converterService) {
this.pharmacyClient = pharmacyClient;
this.converterService = converterService;
}
public Flowable<List<Store>> all() {
Flowable<List<Pharmacy>> listFlowable = this.pharmacyClient.retrieve().map(this.converterService::toPharmacies)
return listFlowable
.doOnError(throwable -> log.error(throwable.getLocalizedMessage()))
.flatMap(pharmacies ->
Flowable.just(pharmacies.stream() // here is a list of LinkedHashMap and i'd like to user Pharmacy objects
.map(pharmacy -> Store.builder().borough(pharmacy.getBoroughFk()).build())
.collect(Collectors.toList())
)
);
}
}
类根目录{
@选择器(value=“.pharmacy”)列出药店;
}
班级药房{
@选择器(value=“span:n子项(1)”)字符串名称;
}
@客户端(${services.minsal.url})
公共接口药剂师{
@Get(${services.minsal.path}?${services.minsal.param}=${services.minsal.value}”)
可流动检索();
}
@独生子女
公共类转换器服务{
公共药物列表(字符串htmlContent){
Jspoon Jspoon=Jspoon.create();
HtmlAdapter HtmlAdapter=jspoon.adapter(Root.class);
返回htmlAdapter.fromHtml(htmlContent).pharmacies;
}
}
公共类存储服务{
私人最终制药公司;
专用最终转换服务转换服务;
公共商店服务(PharmacyClient PharmacyClient、ConverterService ConverterService){
这是。Pharmacycient=Pharmacycient;
this.converterService=converterService;
}
公共可流动全部(){
Flowable listFlowable=this.pharmacyClient.retrieve().map(this.converterService::toPharmacies)
返回列表可流动
.doError(throwable->log.error(throwable.getLocalizedMessage()))
.flatMap(药房->
Flowable.just(pharmacies.stream()//这是LinkedHashMap的列表,我想使用Pharmacy对象
.map(药房->商店.builder().borough(药房.getBoroughFk()).build())
.collect(收集器.toList())
)
);
}
}
我最终得到了这个
@Client("${services.url}")
public interface PharmacyClient {
@Get(value = "${services.path}?${services.param}=${services.value}")
Flowable<Pharmacy[]> retrieve();
}
@Client(${services.url})
公共接口药剂师{
@Get(value=“${services.path}?${services.param}=${services.value}”)
可流动检索();
}
公共类存储服务{
私人最终制药公司;
公共商店服务(PharmacyClient PharmacyClient){
这是。Pharmacycient=Pharmacycient;
}
公共可流动全部(){
Flowable Flowable=this.pharmacyClient.retrieve();
回流
.switchMap(药房->
可流动.just(阵列.stream(药店)
.map(制药企业地图)
.collect(收集器.toList())
)
).doon错误(throwable->log.error(throwable.getLocalizedMessage());
}
}
我仍然想知道是否可以在声明性客户端中将数组更改为列表。同时,我认为这是一个很好的选择 更新 我一直都错了。首先,我不需要向flowable添加列表,因为当框架公开服务时,它已经用元素列表进行响应。 所以最后我做了这个:
@Client("${services.url}")
public interface PharmacyClient {
@Get(value = "${services.path}?${services.param}=${services.value}")
Flowable<Pharmacy> retrieve();
}
@Client(${services.url})
公共接口药剂师{
@Get(value=“${services.path}?${services.param}=${services.value}”)
可流动检索();
}
公共类存储服务{
私人最终制药公司;
公共商店服务(PharmacyClient PharmacyClient){
这是。Pharmacycient=Pharmacycient;
}
公共可流动全部(){
Flowable Flowable=this.pharmacyClient.retrieve();
回流
.switchMap(pharmacyPublisherFunction)
.doon错误(throwable->log.error(throwable.getLocalizedMessage());
}
正如我们所看到的,http客户端自动将文本/html数据转换为json,并能很好地解析。我不知道为什么。也许@JeffScottBrown能给我们一些提示。你是说你想调用一个返回
文本/html
内容类型的响应的服务,你想解析html并创建一个List
来自HTML的内容?是的。但我想知道,如果没有低级http客户端,我是否可以做到这一点。如果有某种方法可以通过声明式客户端做到这一点。Micronaut中没有任何东西可以解析HTML并为您创建List
。您必须自己编写它。@JeffScottBrown和低级http客户?可能有一个过滤器或转换器来翻译数据。“可能有一个过滤器或转换器来翻译数据。”-可以写一个。我们没有
public class StoreService {
private final PharmacyClient pharmacyClient;
public StoreService(PharmacyClient pharmacyClient) {
this.pharmacyClient = pharmacyClient;
}
public Flowable<List<Store>> all() {
Flowable<Pharmacy[]> flowable = this.pharmacyClient.retrieve();
return flowable
.switchMap(pharmacies ->
Flowable.just(Arrays.stream(pharmacies)
.map(pharmacyStoreMapping)
.collect(Collectors.toList())
)
).doOnError(throwable -> log.error(throwable.getLocalizedMessage()));
}
}
@Client("${services.url}")
public interface PharmacyClient {
@Get(value = "${services.path}?${services.param}=${services.value}")
Flowable<Pharmacy> retrieve();
}
public class StoreService {
private final PharmacyClient pharmacyClient;
public StoreService(PharmacyClient pharmacyClient) {
this.pharmacyClient = pharmacyClient;
}
public Flowable<Store> all() {
Flowable<Pharmacy> flowable = this.pharmacyClient.retrieve();
return flowable
.switchMap(pharmacyPublisherFunction)
.doOnError(throwable -> log.error(throwable.getLocalizedMessage()));
}