gpt4 book ai didi

java - 如何在 Java 中以正确的方式将 List<> 项目作为 POST 数据发送?

转载 作者:可可西里 更新时间:2023-11-01 16:20:19 25 4
gpt4 key购买 nike

我正在开发一个 java 服务,其中表 A 中的数据转到表 B。该服务将 POST 请求发送到 REST 服务器,对于复制的每一行,都会创建一个位置 header 作为响应,确认新资源当向新创建的资源发出 GET 请求时,将创建并返回一个 POJO 作为 JSON。这是处理 POST 请求的资源方法。

@POST
@Produces({MediaType.APPLICATION_JSON})
public Response migrateToMinio(@Context UriInfo uriInfo) throws Exception {
tiedostoService = new TiedostoService();
attachmentService = new AttachmentService();
List<Tiedosto> tiedostoList = tiedostoService.getAllFiles();
List<String> responseList = new ArrayList<>();
Response r;
Integer newRow;
String responseData = null;
int i=1;
for (Tiedosto tiedosto : tiedostoList) {
Attachment attachment = new Attachment();
attachment.setCustomerId(tiedosto.getCustomerId());
attachment.setSize(tiedosto.getFileSize());
newRow = attachmentService.createNew(attachment);
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
if (newRow == 1) {
builder.path(Integer.toString(i));
r = Response.created(builder.build()).build();
responseData = r.getLocation().toString();
i++;
}
responseList.add(responseData);
}
String jsonString = new Gson().toJson(responseList);
return Response.status(Response.Status.OK).entity(jsonString).build();
}

tiedostoServiceattachmentService 是两个表的服务类。 tiedostoList 包含 tiedosto 表中的所有行,并在 for 循环内迭代,以便为 tiedostoList 中的每个项目创建附件表中的新行>。当我向 /rest/attachments 发送 POST 请求时,它需要几秒钟的时间来处理并返回状态 200,其中包含一个已创建资源的列表,如下所示: Postman output

现在,我的问题是,有没有一种方法可以实现它,以便在创建后立即返回新创建的资源位置(可能作为 201 创建),而不必等待最终状态 200?

最佳答案

这样的解决方案假定您保存附件的服务 ( AttachmentService ) 能够在保存之前计算出位置。例如,该服务应该能够知道最后一个附件是否以 10 的 ID 存储。 , 下一个附件将以 11 的 ID 存储(或者将计算后续 ID),因此位置为 http://localhost:8080/rest/attachments/11 .

假设该逻辑在您的服务中是可行的,您可以创建一个收据对象,其中包含已创建资源的位置和代表已保存资源的 future 。该收据对象可以由服务而不是附件本身返回。此类收据对象的实现可能类似于以下内容:

public class CreationReceipt<T> {

private final String location;
private final Future<T> attachment;

public CreationReceipt(String location, Future<T> attachment) {
this.location = location;
this.attachment = attachment;
}

public String getLocation() {
return location;
}

public Future<T> getAttachment() {
return attachment;
}
}

AttachmentService , 将存在一种存储新 Attachment 的方法并返回 CreationReceipt<Attachment> :

public class AttachmentService {

public CreationReceipt<Attachment> createNew(Attachment attachment) {
String location = computeLocationFor(attachment);
Future<Attachment> savedAttachment = saveAsynchronously(attachment);
return new CreationReceipt<>(location, savedAttachment);
}

private Future<Attachment> saveAsynchronously(Attachment attachment) { ... }

private String computeLocationFor(Attachment attachment) { ... }
}

预计算 Attachment 位置的逻辑将取决于您的应用程序的具体情况(我将保留它以供您添加逻辑),但是保存 Attachment 的逻辑异步可以遵循一个通用的模式。使用ExecutorService ,用于保存 Attachment 的同步逻辑(您的应用程序已经使用的)可以异步。为此,将同步逻辑提交给 ExecutorService。 (使用 submit 方法)和一个 FutureExecutorService 返回包装保存的 Attachment并将在 Attachment 时完成保存成功。

一个示例(虽然不完整)实现类似于:

public class AttachmentService {

private final ExecutorService executor = Executors.newSingleThreadExecutor();

public CreationReceipt<Attachment> createNew(Attachment attachment) {
String location = computeLocationFor(attachment);
Future<Attachment> savedAttachment = saveAsynchronously(attachment);
return new CreationReceipt<>(location, savedAttachment);
}

private Future<Attachment> saveAsynchronously(Attachment attachment) {
return executor.submit(() -> save(attachment));
}

private Attachment save(Attachment attachment) { ... }

private String computeLocationFor(Attachment attachment) { ... }
}

注意这个实现只允许一个Attachment一次保存(通过使用 Executors.newSingleThreadExecutor() 的性质),但可以通过定义 executor 来更改该逻辑使用不同的 ExecutorService执行。要完成此实现,只需为 save 添加一个实现即可。同步保存新 Attachment 的方法对象(这个同步逻辑应该在你现有的 createNew 方法中从 AttachmentService 中找到)。

从这里开始,保存Attachment的逻辑会是:

List<String> savedLocations = new ArrayList<>();

for (Tiedosto tiedosto : tiedostoList) {
Attachment attachment = new Attachment();
attachment.setCustomerId(tiedosto.getCustomerId());
attachment.setSize(tiedosto.getFileSize());

CreationReceipt<Attachment> receipt = attachmentService.createNew(attachmentToSave);
savedLocations.add(receipt.getLocation());
}

// Do something with savedLocations

这是一个不完整的实现,但它应该演示将要使用的基本结构。循环完成后,您可以包括 saveLocations作为响应的主体并将响应状态代码设置为 201 Created .

关于java - 如何在 Java 中以正确的方式将 List<> 项目作为 POST 数据发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51653357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com