【问题标题】:How do I implement methods using Method Reference inside a map or flatMap如何在地图或 flatMap 中使用方法参考来实现方法
【发布时间】:2021-06-21 16:15:58
【问题描述】:

我正在阅读this,这样我可以更好地理解如何处理异步请求,即使我理解他在这里做什么:

.map(processor::responseToDatabaseEntity) // Create a persistable entity from the response
.map(priceRepository::save)               // Save the entity to the database

我不知道这两种方法将如何实现。假设这个非常简单的代码:

public Mono<Response> postMethod(String id, Person json) {
        return webClient.post().uri(id).body(Mono.just(json), Person.class).retrieve().bodyToMono(Response.class);
}

还有响应类,比如:

public class Response implements Serializable{
    
    private static final long serialVersionUID = -4101206629695985431L;
    
    public String statusCode;
    public Date date;
    public PersonInfo data;

我假设responseToDatabaseEntity 方法是从对 PersonInfoDTO 的响应到数据库的某种转换,save 将插入其中。但是我怎么能使用可以在.map() 中工作的方法参考(::) 来实现类似的东西,所以我可以订阅()之后是我不明白的。

编辑: 添加我所取得的进展,但或多或​​少地适应了我在 Person 类中给出的示例:

public Mono<Object> postPerson(String id, Person json) {
        return webClient.post().uri(id).body(Mono.just(json), Person.class).retrieve().bodyToMono(Response.class).map( c -> {
            List<PersonDTO> list = new ArrayList<PersonDTO>();
            c.data.getRoles().forEach((r) -> {
                PersonDTO dto = new PersonDTO(c.data.getOof(), "something", c.data.getFoo(), r);
                list.add(dto);
            });
            return list;        
        }).map(personController::savePerson).subscribe(); //what I wanted to do
    }

如果我这样做:

    });
    return list;        
}).map(l -> {
        l.
    });

l 包含 PersonDTO 列表,如果我这样做:

  .map(l -> {
        l.forEach( f -> {
            f.
        });
    });

f 包含一个人。

我应该如何实现将整个列表发送到方法中或一个人发送到save的方法。我不能使用像PersonController::savePerson 这样的静态方法,因为:

@RestController
public class PersonController {

    private final Logger LOG = LoggerFactory.getLogger(getClass());

    @Autowired
    private final PersonInterface personRepository;

    public PersonController(PersonInterface personRepository) {
        this.personRepository = personRepository;
    }

personRepository 不能是static

EDIT2:也试过这个,不行:

public List<PersonDTO> savePerson(List<PersonDTO> list) {
        list.forEach(dto -> {
            personRepository.save(dto);
        });
        return list;
}

【问题讨论】:

  • 您能否详细说明您不了解的内容?你的假设是正确的。您可以编写一个返回对象的 map 方法,然后最后调用 subscribe()。对于方法参考 - 这应该会有所帮助 - baeldung.com/java-method-references
  • 我已经编辑了更多细节的评论。

标签: java spring-boot webclient


【解决方案1】:

您可以在任何类中编写responseToDatabaseEntity 方法 - 您可以创建能够转换Entity to Data Objects 和反之亦然的处理器或专用转换器。

在 Stream of Response 实例上调用的 Map 函数将接受对任何方法的引用,该方法采用 Response 实例的单个参数并返回任何类型的对象。

所以,例如我创建了一个专用的转换器

public class EntityDtoTransformer{
    public EntityObject responseToDatabaseEntity(Response response){
        ...
        ...
        return entity;  
    }
}

您可以在地图功能中引用此方法,例如:

entityDtoTransformerInstance::responseToDatabaseEntity

另外,你可以将这个方法设为static,然后在map函数中作为

EntityDtoTransformer::responseToDatabaseEntity

如果你的转换器方法是响应类的一部分,你可以

.map(res -> response.responseToDatabaseEntity)

或缩写形式

.map(Response::responseToDatabaseEntity)

【讨论】:

  • 我试过这个,静态方法有效,但我不想要这个选项,但是第一个没有,它只是说entityDtoTransformerInstance 无法解决。使用我的示例,我在 Response 类中创建了这个:public ResponseDTO responseToDatabaseEntity(Response response){ ResponseDTO a = new ResponseDTO(response); return a; } 并添加了 .map(responseInstance::responseToDatabaseEntity); responseInstance cannot be resolved。
  • 已在答案中涵盖了您的场景
  • 是的,我能够做类似的事情,但我在 .map 中编写了所有操作,而不是创建函数。但是现在的问题是实现save 方法,就像我链接的原始帖子中一样,因为:private final PersonInterface personRepository; public PersonController(PersonInterface personRepository) { this.personRepository = personRepository; } 在另一个名为PersonController 的类中。我不能在这里使用静态方法,因为 personRepository 不能是静态的。我将使用更多详细信息编辑我的评论,但适用于 Person 示例。
  • 非常感谢您的帮助,我已经编辑了我的评论。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 2019-06-14
  • 2019-01-13
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
相关资源
最近更新 更多