如何发送列表<&燃气轮机;项目作为POST数据在Java中的正确方式?
我正在开发一个java服务,其中表a中的数据进入表B。该服务将POST请求发送到REST服务器,对于复制的每一行,将创建一个位置头作为响应,确认创建了一个新资源,并在向新创建的资源发出GET请求时将POJO作为JSON返回。这是处理POST请求的资源方法如何发送列表<&燃气轮机;项目作为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 {
@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