¿Cómo puedo enviar List <> artículos como datos POST de la manera correcta en Java?

Roshan Upreti:

Estoy trabajando en un servicio de java en que los datos de la Tabla A pasa a la tabla B. El servicio envía solicitudes POST a un servidor REST y para cada fila copiada, un encabezado de ubicación se crea como respuesta, lo que confirma que se crea un nuevo recurso y devolver un POJO como JSON petición GET cuando se emite al recurso recién creado. Este es el método de recurso que los mangos Publicar demanda.

@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();
}

tiedostoServicey attachmentServiceson las clases de servicio de dos tablas. tiedostoListtiene todas las filas de tiedostola tabla y ha sido reiteró el interior de bucle de manera que se crea una nueva fila en la tabla de archivos adjuntos de todos los elementos de tiedostoList. Cuando envío a petición POST /rest/attachments, se tarda unos pocos segundos en procesar y regresa estado 200 con una lista de recursos creado de esta manera:salida del cartero

Ahora, mi pregunta es, ¿hay alguna manera de ponerlo en práctica de manera que la ubicación del recurso recién creado se devuelve inmediatamente (tal como 201 creados) después de la creación, sin tener que esperar a que el estatus final de 200?

Justin Albano:

Such a solution would presume that you the service saving the attachment (AttachmentService) would be able to compute the location prior to saving it. For example, the service should be able to know that if the last attachment was stored with an ID of 10, the next attachment would be stored with an ID of 11 (or however the subsequent ID would be calculated) and therefore would have a location of http://localhost:8080/rest/attachments/11.

Presuming that logic is possible in your service, you could create a receipt object that contains the location of the created resource and a future that represents the saved resource. This receipt object can be returned by the service instead of the attachment itself. The implementation of such a receipt object could resemble the following:

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;
    }
}

In AttachmentService, there would exist a method that stores a new Attachment and returns a 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) { ... }
}

The logic for pre-computing the location of an Attachment will depend on the specifics of your application (and I will leave it stubbed for you to add the logic), but the logic for saving an Attachment asynchronously can follow a common pattern. Using an ExecutorService, synchronous logic for saving an Attachment (which your application already uses) can be made asynchronous. To do this, the synchronous logic is submitted to an ExecutorService (using the submit method) and a Future is returned by the ExecutorService which wraps the saved Attachment and will complete when the Attachment is successfully saved.

An example (albeit incomplete) implementation would resemble:

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

Tenga en cuenta que esta aplicación sólo permite un Attachmentser salvado a la vez (por la naturaleza del uso Executors.newSingleThreadExecutor()), pero que la lógica se puede cambiar mediante la definición de executorutilizar una diferente ExecutorServiceaplicación. Para completar esta aplicación, sólo tiene que añadir una implementación para el savemétodo que forma sincrónica ahorra un nuevo Attachmentobjeto (esta lógica síncrona debe encontrarse en su actual createNewmétodo de AttachmentService).

A partir de este punto, la lógica para guardar una Attachmentsería la siguiente:

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

Esta es una implementación imcomplete, pero debe demostrar la estructura básica que se utiliza. Una vez que el bucle se haya completado, se podría incluir saveLocationscomo el cuerpo de la respuesta y establecer el código de estado de respuesta a 201 Created.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=219167&siteId=1
Recomendado
Clasificación