如何发送列表<&燃气轮机;项目作为POST数据在Java中的正确方式?

如何发送列表<&燃气轮机;项目作为POST数据在Java中的正确方式?,java,http,post,jax-rs,Java,Http,Post,Jax Rs,我正在开发一个java服务,其中表a中的数据进入表B。该服务将POST请求发送到REST服务器,对于复制的每一行,将创建一个位置头作为响应,确认创建了一个新资源,并在向新创建的资源发出GET请求时将POJO作为JSON返回。这是处理POST请求的资源方法 @POST @Produces({MediaType.APPLICATION_JSON}) public Response migrateToMinio(@Context UriInfo uriInfo) throws Exception {

我正在开发一个java服务,其中表a中的数据进入表B。该服务将POST请求发送到REST服务器,对于复制的每一行,将创建一个位置头作为响应,确认创建了一个新资源,并在向新创建的资源发出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();
}
@POST
@产生({MediaType.APPLICATION_JSON})
公共响应migrateToMinio(@Context UriInfo UriInfo)引发异常{
tiedostoService=新的tiedostoService();
attachmentService=新的attachmentService();
List tiedostoList=tiedostoService.getAllFiles();
List responseList=new ArrayList();
响应r;
整数新行;
字符串responseData=null;
int i=1;
for(Tiedosto Tiedosto:tiedostoList){
附件=新附件();
附件.setCustomerId(tiedosto.getCustomerId());
附件.setSize(tiedosto.getFileSize());
newRow=attachmentService.createNew(附件);
UriBuilder=uriInfo.getAbsolutePathBuilder();
if(newRow==1){
builder.path(Integer.toString(i));
r=Response.created(builder.build()).build();
responseData=r.getLocation().toString();
i++;
}
响应列表。添加(响应数据);
}
字符串jsonString=new Gson().toJson(responseList);
返回Response.status(Response.status.OK).entity(jsonString.build();
}
tiedostoService
attachmentService
是两个表的服务类
tiedostoList
包含
tiedosto
表中的所有行,并且在for循环中进行了迭代,以便在附件表中为
tiedostoList
中的每个项目创建新行。当我向
/rest/attachments
发送POST请求时,需要几秒钟的时间来处理并返回状态200以及创建的资源列表,如下所示:


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

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

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

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;
    }
}
用于预计算
附件位置的逻辑取决于应用程序的具体情况(我会让您添加逻辑),但用于异步保存
附件的逻辑可以遵循一种常见模式。使用
ExecutorService
,用于保存
附件的同步逻辑(您的应用程序已经使用)可以变得异步。为此,同步逻辑被提交到
执行器服务
(使用
提交
方法),并且
执行器服务
返回一个
未来
,它包装保存的
附件
,并在
附件
成功保存后完成

示例(尽管不完整)实现类似于:

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) { ... }
}
这是一个不完整的实现,但它应该演示将要使用的基本结构。循环完成后,您可以将
saveLocations
作为响应主体,并将响应状态代码设置为
201 Created

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) { ... }
}
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