Multiple shipments in Spring Boot

Asked

Viewed 229 times

1

I’m having trouble sending several images, I receive all the files and in the loop I do the interaction, but only send and register an image. I’m doing it wrong?

Follow the project in my github

@PostMapping("/galeria/enviar")
public String enviarGaleria(GalleryModel gallery, @RequestParam("ref_gallery") Long ref, @RequestParam("img_gallery") MultipartFile[] galleries) throws IOException {
    for(MultipartFile gy : galleries) {
        Path galleryNameAndPath = Paths.get(uploadDirectory, gy.getOriginalFilename());
        Files.write(galleryNameAndPath, gy.getBytes());

        gallery.setPostId(ref);
        gallery.setImage(gy.getOriginalFilename());
        galleryRepository.save(gallery);
    }

    return "redirect:/anuncios";
}
  • Well if you are saving only one you are probably getting only one, if possible edit the question and include the code you are using to send, I have never used Multipartfile this way, I have thus working @Requestparam(name = "files", required = true) List<Multipartfile> files,

  • Edited question, put the project on my github, feel free to evaluate the problem :D

  • I downloaded your Github project and found the problem, then put the solution and send you a pull request

1 answer

0


The problem lies in your data modeling, your class implementation GalleryModel does not have support for multiple photos since you are saving in a string:

@Column(name="image", nullable=false)
private String image;

I checked your project and made some adjustments, but in fact the files arrive to your app (as evidenced below)

inserir a descrição da imagem aqui

When checking the operations performed in the bank, you can see that an insertion has been performed, and then the same gallery has been updated in subsequent calls:

Hibernate: insert into posts (author, category, content, cover, created_at, method, price, sale, status, title, updated_at, uri, views) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into galleries (created_at, image, post_id) values (?, ?, ?)
Hibernate: update galleries set created_at=?, image=?, post_id=? where id=?
Hibernate: update galleries set created_at=?, image=?, post_id=? where id=?
Hibernate: update galleries set created_at=?, image=?, post_id=? where id=?

That way you’re always saving the last photo from the loop, when in fact you should be saving all the photos and relating them to the gallery itself.

To solve this I created an associative table called gallery_photo, that will store the gallery photo records, and I changed the association in class gallery:

@Data
@Entity
@Table(name="galleries")
public class GalleryModel implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(name="post_id", nullable=false)
    private long postId;

    @Column(name="created_at", columnDefinition="TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP")
    private Date createdAt;

    @ManyToMany(mappedBy = "gallery", cascade = CascadeType.ALL)
    private Set<GalleryPhotoModel> photos;

}

@Data
@Entity
@Table(name="gallery_photo")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class GalleryPhotoModel {

    public GalleryPhotoModel(String image) {
        super();
        this.image = image;
    }

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column
    private String image;

    @ManyToOne
    private GalleryModel gallery;
}

Now when inserting the galleries, all photos are saved:

Hibernate: insert into posts (author, category, content, cover, created_at, method, price, sale, status, title, updated_at, uri, views) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into galleries (created_at, post_id) values (?, ?)
Hibernate: insert into gallery_photo (gallery_id, image) values (?, ?)
Hibernate: insert into gallery_photo (gallery_id, image) values (?, ?)
Hibernate: insert into gallery_photo (gallery_id, image) values (?, ?)
Hibernate: insert into gallery_photo (gallery_id, image) values (?, ?)

Oh another thing, I suggest you create a new layer in your application to services, to isolate the service layer (rules, conversions, etc...) of your controller, and thus reuse more code. I refactored the code that inserts the gallery, always remember the principle DRY (Don’t Repeat Yourself!), now the method has gone like this:

private void salvarGalerias(GalleryModel gallery, Long postId, List<MultipartFile> galleries) throws IOException {
    for(MultipartFile gy : galleries) {
        Path galleryNameAndPath = Paths.get(uploadDirectory, gy.getOriginalFilename());
        Files.write(galleryNameAndPath, gy.getBytes());
    }

    gallery.setPostId(postId);
    gallery.setCreatedAt(new Date(System.currentTimeMillis()));
    gallery.setPhotos(galleries.stream().map(MultipartFile::getOriginalFilename).map(GalleryPhotoModel::new).collect(Collectors.toSet()));
    galleryRepository.save(gallery);

}

It should be called whenever you insert a new galleries, this method should be used (hence the idea of extracting it for a GalleryService):

@PostMapping("/publicar")
public String postPublish(PostModel post, GalleryModel gallery,
        @RequestParam("img_cover") MultipartFile cover,
        @RequestParam("img_gallery") MultipartFile[] galleries) throws IOException {
    Path fileNameAndPath = Paths.get(uploadDirectory, cover.getOriginalFilename());
    Files.write(fileNameAndPath, cover.getBytes());

    post.setAuthor(authUtility.getUserLogged().getId());
    post.setCover(cover.getOriginalFilename());
    post.setStatus(1);
    post.setPrice(post.getPrice().replace(",", "."));
    post.setUri(uriUtility.uri(post.getTitle()));
    post.setCreatedAt(new Date(System.currentTimeMillis()));
    postRepository.save(post);

    salvarGalerias(gallery, post.getId(), Arrays.asList(galleries));

    return "redirect:/publicar";
}

@PostMapping("/galeria/enviar")
public String enviarGaleria(GalleryModel gallery, @RequestParam("ref_gallery") Long postId,
        @RequestParam(name="img_gallery", required=true) List<MultipartFile> galleries) throws IOException {
    salvarGalerias(gallery, postId, galleries);

    return "redirect:/anuncios";
}

There are several other details to correct (names of entities and tables, use Dtos and not entities for interaction with the controllers, layers of the app...), but for the purpose you wanted this will help you already :)

  • First of all, I wanted to thank you for your help, and I think you’ve taken some time off from your rest for this problem, but I am very grateful for the support that you sincerely needed, because you were already breaking your head and thinking about doing it differently. But then, looking at your code became clearer, but at the same time I noticed a problem and kind of do not know how to proceed, the problem is that at the moment register the gallery gallery_id does not receive the id of the galleries. Sincerely for lack of experience I am not able to see the error, could you give me a light?

  • in what situation is happening?

  • Hello, sorry for the delay, but it happens when I make a product publication and everything goes and the images and even in the registered bank, but only information that does not register is the gallery_id.

  • Open another question explaining the problem better, when I have a little time I can help you

Browser other questions tagged

You are not signed in. Login or sign up in order to post.