Comment puis-je envoyer la liste <> articles en tant que données POST la bonne façon en Java?

Roshan Upreti:

Je travaille sur un service de Java où les données du tableau A va au tableau B. Le service envoie des requêtes POST à ​​un serveur REST et pour chaque ligne copiée, un en-tête de l'emplacement est créé comme une réponse, ce qui confirme qu'une nouvelle ressource est créée et retour d'un POJO comme JSON lorsque la demande GET est émise à la ressource nouvellement créée. Ceci est la méthode de ressource poignées requêtes 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();
}

tiedostoServiceet attachmentServicesont des classes de service pour deux tables. tiedostoLista toutes les lignes de la tiedostotable et a été répété à l' intérieur de la boucle de sorte qu'une nouvelle ligne de la table des pièces jointes est créé pour chaque élément tiedostoList. Lorsque j'envoie la demande POST /rest/attachments, il faut quelques secondes pour traiter et retourne l' état 200 avec une liste de ressources créée comme ceci:sortie Postman

Maintenant, ma question est, est-il un moyen de mettre en œuvre pour que le nouveau lieu de ressource est retourné immédiatement (peut-être que 201 créé) après la création de, sans avoir à attendre que le statut final 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) { ... }
}

Notez que cette mise en œuvre ne permet qu'une seule Attachmentà enregistrer à la fois (par la nature de l' utilisation Executors.newSingleThreadExecutor()), mais cette logique peut être modifiée en définissant executord'utiliser une autre ExecutorServicemise en œuvre. Pour compléter cette mise en œuvre, il suffit d' ajouter une mise en œuvre de la saveméthode qui enregistre de manière synchrone un nouvel Attachmentobjet (cette logique synchrone doit se trouver dans votre actuelle createNewméthode à partir AttachmentService).

De ce point, la logique de l' enregistrement d' un Attachmentserait:

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

Ceci est une mise en œuvre imcomplete, mais il doit démontrer la structure de base qui serait utilisée. Une fois que la boucle est terminée, vous pouvez inclure saveLocationsque le corps de la réponse et de définir le code d'état de réponse 201 Created.

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=219165&siteId=1
conseillé
Classement