I try the upload of a user picture with the MultipartFile process but I always get the same error message of "charset=UTF-8" is not supported ... I tried many annotations as @PostMapping(path="/new", consumes={MediaType.APPLICATION_JSON_UTF8_VALUE}) and others solutions I found here in SOF but nothing works!
May the Spring Security configuration be faulty in this case (I assume no) ? ... I run a basic mirror project without Spring Security and it's working ...
I run my tests with Postman Postman
It seems that the entire request made with Body/form-data is rejected but if I run it with Body/raw/json (without the file) it's going perfectly!
** user entity **
@Entity
@Table(name="user", uniqueConstraints = {
@UniqueConstraint(columnNames = "username"),
@UniqueConstraint(columnNames = "email")
})
public class User {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
@Column(name="username")
private String username;
@Column(name="password")
private String password;
@Column(name="avatar")
private String avatar;
@Column(name="email")
private String email;
@Column(name="bio")
private String bio;
@Column(name = "created_at")
private Date createdAt;
@Column(name="updated_at")
private Date updatedAt;
@ManyToMany(fetch = FetchType.LAZY)
@JsonIgnore
@JoinTable(name="user_role",
joinColumns = @JoinColumn(name="user_id"),
inverseJoinColumns = @JoinColumn(name="role_id"))
private Set<Role> roles = new HashSet<>();
@OneToMany(mappedBy = "donor", cascade = CascadeType.ALL)
@JsonIgnore
// liste des donations par donateurs
private Set<Donation> donationsByDonor = new HashSet<>();
@OneToMany(mappedBy = "beneficiary", cascade = CascadeType.ALL)
@JsonIgnore
// liste des donations par bénéficiaire
private Set<Donation> donationsByBeneficiary = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
// liste des evaluations par user
private Set<Evaluation> evaluations = new HashSet<>();
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
@JsonIgnore
// Liste des pdfs par user
private Set<Pdf> pdfs = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnore
// liste des recherches par user
private Set<Search> searches = new HashSet<>();
@OneToMany(mappedBy = "alertLauncher", cascade = CascadeType.ALL)
@JsonIgnore
// liste alerts par user
private Set<Alert> alertList = new HashSet<>();
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(String username, String email, String password, String avatar) {
this.username = username;
this.email = email;
this.password = password;
this.avatar = avatar;
}
public User(String username, String password, String avatar, String email, String bio, Date createdAt, Date updatedAt, Set<Role> roles, Set<Donation> donationsByBeneficiary, Set<Donation> donationsByDonor, Set<Evaluation> evaluations, Set<Pdf> pdfs, Set<Search> searches, Set<Alert> alertList) {
this.username = username;
this.password = password;
this.avatar = avatar;
this.email = email;
this.bio = bio;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.roles = roles;
this.donationsByBeneficiary = donationsByBeneficiary;
this.donationsByDonor = donationsByDonor;
this.evaluations = evaluations;
this.pdfs = pdfs;
this.searches = searches;
this.alertList = alertList;
}
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public Set<Donation> getDonationsByDonor() {
return donationsByDonor;
}
public void setDonationsByDonor(Set<Donation> donationsByDonor) {
this.donationsByDonor = donationsByDonor;
}
public Set<Donation> getDonationsByBeneficiary() {
return donationsByBeneficiary;
}
public void setDonationsByBeneficiary(Set<Donation> donationsByBeneficiary) {
this.donationsByBeneficiary = donationsByBeneficiary;
}
public Set<Evaluation> getEvaluations() {
return evaluations;
}
public void setEvaluations(Set<Evaluation> evaluations) {
this.evaluations = evaluations;
}
public Set<Pdf> getPdfs() {
return pdfs;
}
public void setPdfs(Set<Pdf> pdfs) {
this.pdfs = pdfs;
}
public Set<Search> getSearches() {
return searches;
}
public void setSearches(Set<Search> searches) {
this.searches = searches;
}
public Set<Alert> getAlertList() {
return alertList;
}
public void setAlertList(Set<Alert> alertList) {
this.alertList = alertList;
}
}
**Dto from client **
@Data
public class UserDTOWayIN {
String username;
String password;
String avatar;
String email;
String bio;
Date createdAt;
Date updatedAt;
Set<Role> roles;
}
**Dto to client **
@Data
public class UserDTO {
Long Id;
String username;
String bio;
Date createdAt;
Date updatedAt;
Set<Role> roles;
}
**UserController with the signup endpoint **
@CrossOrigin(origins = "http://localhost:4200", maxAge = 3600)
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService service;
@Autowired
private ModelMapper modelMapper;
public static String uploadDirectory = System.getProperty("user.dir")+"/src/main/webapp/avatars/";
@PostMapping(path="/new", consumes={MediaType.APPLICATION_JSON_UTF8_VALUE})
@PreAuthorize("hasRole('ADMIN'), hasRole('USER')")
public ResponseEntity<UserDTO> saveUser(@ModelAttribute UserDTOWayIN clientDatas, @RequestParam("file")MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();
Path fileNameAndPath= Paths.get(uploadDirectory, originalFilename);
Files.write(fileNameAndPath, file.getBytes());
clientDatas.setAvatar(originalFilename);
// Conversion des datas front en DTOWayIN
UserDTOWayIN userDTOWayIN = modelMapper.map(clientDatas, UserDTOWayIN.class);
// Conversion sens DTOWayIN à Entité
User user = service.saveUser(userDTOWayIN);
// Conversion sens Entité à DTO
UserDTO userDTO = modelMapper.map(user, UserDTO.class);
return new ResponseEntity<UserDTO>(userDTO, HttpStatus.CREATED);
}
If we want to send json and multipartFile in same API request refer below example
Postman curl for above API