在发送包含文件,字符串和后端的对象的对象时问题

发布于 2025-02-12 04:16:55 字数 9445 浏览 0 评论 0 原文

我正在制作 Contact Manager Application 与电话联系类似申请。 前端 - react + redux 后端-Spring Boot

项目链接 - https://github.com/ debrajhyper/personal-contact-manager

在发送 add_contact 数据时,我无法按照后端的预期接收数据。 我想将数据发送为对象的对象,其中包含图片,字符串和对象。因此,我必须使用 formdata ,但是使用FormData,我无法在后端发送对象,因为它将全部转换为字符串,在后端,我使用 @modelattribute @requestparam 求抓取请求。

我正在使用此值USESTATE 将数据存储在前端

const [values, setValues] = useState({
        profilePic: "",
        profilePicURL: "",
        favorite: false,
        name: "",
        nickName: "",
        title: "",
        company: "",
        email: "",
        telephoneNumber: {
            code: "",
            number: ""
        },
        country: {
            code: "",
            name: "",
            no: ""
        },
        dateOfBirth: "",
        address: "",
        relationship: "",
        zodiacSign: "",
        tags: [],
        website: "",
        socialLinks: {
            facebook: "",
            twitter: "",
            linkedIn: "",
            instagram: "",
            youtube: "",
        },
        description: "",
    });

和Redux端,我正在使用Axios生成请求

const config = {
    headers: {
        'content-type': 'multipart/form-data; boundary=<calculated when request is sent>'
    }
}

export const addContact = (contact) => {
    return dispatch => {
        dispatch(contactRequest());

         const createFormData = (data) => {
             return Object.keys(data).reduce((formData, key) => {
                  formData.append(key, data[key]);
                  return formData;
             }, new FormData());
         };
         const data = createFormData(contact);

        axiosPrivate.post("http://localhost:1010/add-contact", data, config)
        .then(response => {
            dispatch(contactSuccess(response?.data));
        })
        .catch(error => {
            dispatch(contactFailure(error?.response?.data?.message));
            const errorMessage = error?.response?.data?.message?.length > 100 ? 'Something went wrong' : error?.response?.data?.message;
        })
    }
};

--------------------------------------------------------------------------------- ------------- 模式

--------------------------------------------在后端,我用来存储数据 contact.java

package com.pcm.Model;

import java.sql.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.Past;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;


@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "contact")
public class Contact {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int cId;
    
    private String image;
    
    private boolean favorite;
    
    private String name;
    
    private String nickName;
    
    private String title;
    
    private String company;
    
    @Column(unique = true)
    private String email;
    
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactTelephoneNumber telephoneNumber;
    
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactCountryName country;
    
    @JsonFormat(pattern = "dd/MM/yyyy")
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    @Past(message = "The date of birth must be in the past")
    private Date dateOfBirth;
    
    private String address;
    
    private String relationship;
    
    private String zodiacSign;
    
    private String[] tags;

    @Column(length = 9000)
    private String description;
    
    private String website;
    
    @Valid
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactSocialLinks socialLinks;

    @JsonIgnore
    @ManyToOne
    private User user;

}

contacttelephonenumber.java 模态

package com.pcm.Model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;


@Data
@Entity
@Table(name = "telephone_number")
public class ContactTelephoneNumber {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    private String code;
    
    private String number;
    
    @JsonIgnore
    @OneToOne
    @JoinColumn(name = "contact_id")
    private Contact contact;
    
}

----------------------- ------------------ 控制器 --------------------------------------------------------------------- -

package com.pcm.Controller;

import java.security.Principal;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.pcm.Model.Contact;
import com.pcm.Service.ContactService;


@CrossOrigin("*")
@RestController
public class ContactController {
    
    @Autowired
    private ContactService contactService;
    
    @PostMapping("/add-contact")
    public ResponseEntity<String> addContact(@Valid @ModelAttribute Contact contact, @RequestParam("profilePic") MultipartFile profilePic, Principal principal ) throws Exception {
        
        String email = principal.getName();
        
        User user = this.userRepository.findByUserName(email);
        
        List<Contact> contactsByUser = this.contactRepository.findContactsByUser(user.getId());
        ListIterator<Contact> iterateContactList = contactsByUser.listIterator();
        while(iterateContactList.hasNext()) {
            if(iterateContactList.next().getEmail().equals(contact.getEmail())) {
                  throw new DuplicateKeyException("Contact already exist");
            }
        }
        
        if(profilePic.isEmpty()) {
            System.out.println("IMAGE FILE EMPTY");
            contact.setImage("default.png");
        } 
        else if(!profilePic.getContentType().equals("image/jpeg") && !profilePic.getContentType().equals("image/png")) {
            throw new ValidationException("Only JPEG/PNG content type are allowed");
        } 
        else {
            String imageName = contact.getCId() + "_" + profilePic.getOriginalFilename();
            
            contact.setImage(imageName);
            System.out.println("PROFILE PIC IMAGE NAME -> " + imageName);
            
            File saveFile = new ClassPathResource("static/upload/").getFile();
            Path path = Paths.get(saveFile.getAbsolutePath() + File.separator + imageName);
            System.out.println("IMAGE LOCATION -> " + path);
            
            Files.copy(profilePic.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("IMAGE FILE SUCCESSFULLY UPLOADED");
        }

        if(contact.getTelephoneNumber() != null) {
            contact.getTelephoneNumber().setContact(contact);
        }
        if(contact.getCountry() != null) {
            contact.getCountry().setContact(contact);
        }
        if(contact.getSocialLinks() != null) {
            contact.getSocialLinks().setContact(contact);
        }
        
        contact.setUser(user);
        
        User savedUserContact = this.userRepository.save(user);
        
        return new ResponseEntity<String>("Contact Added Successfully", HttpStatus.OK);
    }
}

我想在值usestate 中作为包含文件,字符串和对象的对象的对象发送数据。并想将请求存储在 contact.java模式中,

任何人都可以帮助我找出任何解决方案。 您可以在

I am making a contact manager application similarly to phone contact applications.
Front End - React + Redux
Backend - Spring Boot

Project Link - https://github.com/debrajhyper/Personal-Contact-Manager

while Sending the add_contact data with Axios I am not able to receive data as expected in the backend.
I want to send data as an object of objects which contains pictures, strings, and objects. So I have to use formdata but with formdata I cannot send objects in the backend as it converts all to strings and in the backend, I'm using @ModelAttribute and @RequestParam to catch the request.

I am using this values usestate to store the data in frontend

const [values, setValues] = useState({
        profilePic: "",
        profilePicURL: "",
        favorite: false,
        name: "",
        nickName: "",
        title: "",
        company: "",
        email: "",
        telephoneNumber: {
            code: "",
            number: ""
        },
        country: {
            code: "",
            name: "",
            no: ""
        },
        dateOfBirth: "",
        address: "",
        relationship: "",
        zodiacSign: "",
        tags: [],
        website: "",
        socialLinks: {
            facebook: "",
            twitter: "",
            linkedIn: "",
            instagram: "",
            youtube: "",
        },
        description: "",
    });

and on the redux side, I am generating requests with Axios

const config = {
    headers: {
        'content-type': 'multipart/form-data; boundary=<calculated when request is sent>'
    }
}

export const addContact = (contact) => {
    return dispatch => {
        dispatch(contactRequest());

         const createFormData = (data) => {
             return Object.keys(data).reduce((formData, key) => {
                  formData.append(key, data[key]);
                  return formData;
             }, new FormData());
         };
         const data = createFormData(contact);

        axiosPrivate.post("http://localhost:1010/add-contact", data, config)
        .then(response => {
            dispatch(contactSuccess(response?.data));
        })
        .catch(error => {
            dispatch(contactFailure(error?.response?.data?.message));
            const errorMessage = error?.response?.data?.message?.length > 100 ? 'Something went wrong' : error?.response?.data?.message;
        })
    }
};

------------------------------ Modals ------------------------------

and on the backend the modal I used to store the data Contact.java

package com.pcm.Model;

import java.sql.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.Past;

import org.springframework.format.annotation.DateTimeFormat;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;


@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "contact")
public class Contact {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int cId;
    
    private String image;
    
    private boolean favorite;
    
    private String name;
    
    private String nickName;
    
    private String title;
    
    private String company;
    
    @Column(unique = true)
    private String email;
    
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactTelephoneNumber telephoneNumber;
    
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactCountryName country;
    
    @JsonFormat(pattern = "dd/MM/yyyy")
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    @Past(message = "The date of birth must be in the past")
    private Date dateOfBirth;
    
    private String address;
    
    private String relationship;
    
    private String zodiacSign;
    
    private String[] tags;

    @Column(length = 9000)
    private String description;
    
    private String website;
    
    @Valid
    @OneToOne(mappedBy = "contact", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private ContactSocialLinks socialLinks;

    @JsonIgnore
    @ManyToOne
    private User user;

}

The ContactTelephoneNumber.java Modal

package com.pcm.Model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;


@Data
@Entity
@Table(name = "telephone_number")
public class ContactTelephoneNumber {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    private String code;
    
    private String number;
    
    @JsonIgnore
    @OneToOne
    @JoinColumn(name = "contact_id")
    private Contact contact;
    
}

------------------------------ Controller ------------------------------

package com.pcm.Controller;

import java.security.Principal;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.pcm.Model.Contact;
import com.pcm.Service.ContactService;


@CrossOrigin("*")
@RestController
public class ContactController {
    
    @Autowired
    private ContactService contactService;
    
    @PostMapping("/add-contact")
    public ResponseEntity<String> addContact(@Valid @ModelAttribute Contact contact, @RequestParam("profilePic") MultipartFile profilePic, Principal principal ) throws Exception {
        
        String email = principal.getName();
        
        User user = this.userRepository.findByUserName(email);
        
        List<Contact> contactsByUser = this.contactRepository.findContactsByUser(user.getId());
        ListIterator<Contact> iterateContactList = contactsByUser.listIterator();
        while(iterateContactList.hasNext()) {
            if(iterateContactList.next().getEmail().equals(contact.getEmail())) {
                  throw new DuplicateKeyException("Contact already exist");
            }
        }
        
        if(profilePic.isEmpty()) {
            System.out.println("IMAGE FILE EMPTY");
            contact.setImage("default.png");
        } 
        else if(!profilePic.getContentType().equals("image/jpeg") && !profilePic.getContentType().equals("image/png")) {
            throw new ValidationException("Only JPEG/PNG content type are allowed");
        } 
        else {
            String imageName = contact.getCId() + "_" + profilePic.getOriginalFilename();
            
            contact.setImage(imageName);
            System.out.println("PROFILE PIC IMAGE NAME -> " + imageName);
            
            File saveFile = new ClassPathResource("static/upload/").getFile();
            Path path = Paths.get(saveFile.getAbsolutePath() + File.separator + imageName);
            System.out.println("IMAGE LOCATION -> " + path);
            
            Files.copy(profilePic.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("IMAGE FILE SUCCESSFULLY UPLOADED");
        }

        if(contact.getTelephoneNumber() != null) {
            contact.getTelephoneNumber().setContact(contact);
        }
        if(contact.getCountry() != null) {
            contact.getCountry().setContact(contact);
        }
        if(contact.getSocialLinks() != null) {
            contact.getSocialLinks().setContact(contact);
        }
        
        contact.setUser(user);
        
        User savedUserContact = this.userRepository.save(user);
        
        return new ResponseEntity<String>("Contact Added Successfully", HttpStatus.OK);
    }
}

I want to send data as i mention in the values usestate as object of objects which contains file, strings and objects. And want to store the request in Contact.java Modal

Can anyone help me in figuring out any solution.
you can look out my project in https://github.com/debrajhyper/Personal-Contact-Manager

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文