Multipartfile charset=UTF-8 is not supported spring boot api rest - spring

The code was working normally and I've tried in every way to solve it and I couldn't, it may be that after I transformed the MultipartFile into an array this happened
#RestController
#RequestMapping("products")
public class ProductController {
#Autowired
private ProductService productService;
#PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
#Transactional
public ResponseEntity<ShowProductsDTO> registerProduct(
#RequestBody #Valid ProductDTO dto,
#RequestParam(name = "files", required = true) MultipartFile[] files,
UriComponentsBuilder uriBuilder) {
ShowProductsDTO showProductsDTO = null;
try {
showProductsDTO = productService.save(dto, files);
} catch (IOException e) {
e.printStackTrace();
}
var uri = uriBuilder.path("/products/{id}").buildAndExpand(showProductsDTO.id()).toUri();
return ResponseEntity.created(uri).body(showProductsDTO);
}
DTO
public record ProductDTO(
#NotBlank
String name,
#NotBlank
String description,
#NotNull
#NumberFormat
BigDecimal price,
#NumberFormat
#NotNull
Integer quantity,
#NotNull
Boolean active,
#NotNull
Long sub_category_id
) {
}
Error console
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException:
Content-Type
'multipart/form-data;boundary=--------------------------816548045966415708649211;charset=UTF-8'
is not supported]
Postman body > raw > json
{
"name": "Nome do produto",
"description": "descricao do produto",
"price": "2500.00",
"quantity": "2",
"active": "true",
"sub_category_id": "1"
}
Postman > body > form-data
KEY "files", TYPE file, VALUE uma imagem minha em png
Error postman
{
"timestamp": "2023-01-11T06:15:43.455+00:00",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content-Type 'multipart/form-data;boundary=--------------------------056640214920648036756520;charset=UTF-8' is not supported.",
"path": "/products"
}
Product entity
#Table(name = "products")
#Entity(name = "Product")
#Getter
#Setter
#NoArgsConstructor
#EqualsAndHashCode(of = "id")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 100, unique = true, nullable = false)
private String name;
#Column(nullable = false, columnDefinition = "TEXT")
private String description;
#Column(length = 8, nullable = false, columnDefinition = "NUMERIC(8,2)")
private BigDecimal price;
#Column(nullable = false, columnDefinition = "INT")
private Integer quantity;
#Column(nullable = false, columnDefinition = "BOOLEAN")
private Boolean active;
#CollectionTable(name = "products_files",
joinColumns =
#JoinColumn(name = "product_id", referencedColumnName = "id"))
private List<String> productFiles;
#JoinColumn(name = "sub_category_id")
#ManyToOne(fetch = FetchType.EAGER)
private SubCategory subCategory;
how do I fix this error?

Change your attribute to #PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
and call your api using Postman body > raw > json.
The thing is, Content-Type: form-data handles file requests.

Related

Sending file and JSON in a many-to-many relationship

I have a model called EPI that has a many to many relationship with Model Images, I am not able to do the #PostMapping for this object.
see my code
EPI Entity:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Table(name = "EPI")
public class EPI implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Id_EPI")
private UUID id;
#Column(name = "Nome", nullable = false, length = 100)
private String nome;
#Column(name = "Marca", nullable = false, length = 100)
private String marca;
#Column(name = "CA", nullable = false, length = 100)
private String ca;
#Column(name = "Descricao", nullable = false)
private String descricao;
#Column(name = "Foto")
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "epi_images",
joinColumns = {
#JoinColumn(name = "epi_id")
},
inverseJoinColumns = {
#JoinColumn(name = "image_id")
})
private Set<ImageModel> foto;
#Column(name = "Quantidade", nullable = false)
private Integer quantidade;
}
Image Entity:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Table(name = "image_model")
public class ImageModel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
#Column(name = "type")
private String type;
#Column(name = "image_data", unique = false, nullable = false, length = 100000)
private byte[] imageData;
}
Controller EPI:
#PostMapping("/addNewEPI")
public ResponseEntity<Object> salvarFEPI(#RequestPart("image")MultipartFile file,
#RequestPart("epiModel") EPI epi) throws IOException {
try {
ImageModel foto = productImageService.uploadImage(file);
epi.setFoto((Set<ImageModel>) foto);
return ResponseEntity.status(HttpStatus.CREATED).body(epiService.save(epi));
} catch (Exception e){
System.out.println(e.getMessage());
return null;
}
Service Image:
public ImageModel uploadImage(MultipartFile file) throws IOException {
ImageModel image = new ImageModel();
image.setName(file.getOriginalFilename());
image.setType(file.getContentType());
image.setImageData(ImageUtility.compressImage(file.getBytes()));
return image;
}
As I am passing the parameters in Postman:
enter image description here
Return from Spring Boot:
enter image description here
If anyone can help me I would be very grateful!
I tried passing the parameters in different ways. I just want it to populate my tables passing the parameters of the EPI entity and the Image file.
enter image description here

How to insert an object inside another in Spring

I'm trying to insert the Insurance object into **User **through an endpoint in Spring, but either the request asks me for all User attributes or the object is not inserted.
**User Class **
#Entity
#Table(name = "users",
uniqueConstraints = {
#UniqueConstraint(columnNames = "username"),
#UniqueConstraint(columnNames = "email")
})
#AllArgsConstructor
#NoArgsConstructor
#Data
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotBlank
#Size(max = 20)
private String username;
private String documento;
private String telefone;
#Value("${some.key:false}")
private boolean first_acess;
private String formacao;
private String sexo;
private String data_nascimento;
#NotBlank
#Size(max = 50)
#Email
private String email;
#NotBlank
#Size(max = 120)
private String password;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable( name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
#Embedded
private Address address;
#ManyToOne
#JoinColumn(name = "insuranceId")
private Insurance insurance;
Insurance class
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "insurance")
public class Insurance {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long insuranceId;
private String name;
private String valor;
private String maximoDependentes;
private String vencimento;
private String descricao;
}
Request to insert into class
#PostMapping("/User/{id}/addPlan")
public ResponseEntity<User> addPlanToUser(#PathVariable("id") long id, #RequestBody SignInsuranceRequest signInsuranceRequest) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found User with id = " + id));
return new ResponseEntity<>(userRepository.save(user), HttpStatus.OK);
}
Custom request for the solution
public class SignInsuranceRequest {
#ManyToOne
#JoinColumn(name = "insuranceId", insertable = false, updatable = false)
private Insurance insurance;
public Insurance getInsurance() {
return insurance;
}
public void setInsurance(Insurance insurance) {
this.insurance = insurance;
}
}
I already tried to put the User in #RequestBody and just ask for the insurance and it didn't work either
Example of how it was done
#PutMapping("/User/{id}/addPlan")
public ResponseEntity<User> addPlanToUser(#PathVariable("id") long id, #RequestBody User user) {
User _user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Not found User with id = " + id));
_user.setInsurance(user.getInsurance());
return new ResponseEntity<>(userRepository.save(_user), HttpStatus.OK);
}
In this attempt, I would pass the id of an insurance in the body of the request and the ID of the user in the Header but the id of the database was not retrieved.
Response
{
"id": 1,
"username": "user",
"documento": null,
"telefone": null,
"first_acess": false,
"formacao": null,
"sexo": null,
"data_nascimento": null,
"email": "user#user.com",
"password": "$2a$10$DUkVRxFFiR7L2OpwwpxHyOCC.7v/iFLqp66BBqy3AC0lHrVa9lnQK",
"roles": [],
"address": null,
"insurance": {
"insuranceId": 1,
"name": "string",
"valor": "string",
"maximoDependentes": "string",
"vencimento": "string",
"descricao": "string"
}
}
I expected to insert an User class into a Insurance Class(Already created) and return the object of User completed.

how to specify List of entites in an entity using JPA

I have two entities. A vulnerability can have multiple vulnerability identifiers.
#Entity
#JsonInclude(Include.NON_NULL)
#ApiModel(parent = ApprovableEntity.class)
public class Vulnerability {
...
#JsonProperty("vulnerabilityIdentifiers")
#JoinColumn(name = "vulnerabilityidentifier_id")
#JsonView(JsonViews.BasicChangeLogView.class)
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<VulnerabilityIdentifier> vulnerabilityIdentifiers;
...
}
#Entity
#ApiModel(parent = ApprovableEntity.class)
public class VulnerabilityIdentifier {
...
#ManyToOne
#JoinColumn(name = "vulnerability_id", referencedColumnName = "id")
#NotNull(message = "vulnerability is required")
#JsonView({JsonViews.BasicApprovableView.class, JsonViews.BasicChangeLogView.class,
JsonViews.ChangeLogAnswerView.class, JsonViews.DraftAnswerView.class})
#ApiModelProperty(hidden = true)
private Vulnerability vulnerability;
#Column(name = "type")
#JsonProperty("type")
#Size(max = 12)
#NotNull(message = "CVEID type required")
#ApiModelProperty(accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private String cveIdType;
#Column(name = "value")
#JsonProperty("value")
#Size(max = 24)
#NotNull(message = "value is required")
#ApiModelProperty(accessMode = ApiModelProperty.AccessMode.READ_ONLY)
private String value;
...
}
Now when I send in a json request to the endpoint like as under, the application throws exception that it cannot map the type and value fields in the vulnerabilityIdentifier field.
A sample json request
{
"vulnerabilityImpacts": {
},
"vulnerabilityIdentifiers": [{"type": "cveId", "value": "CVE-1234-12345"}],
"vulnerableThreeppcomponents": [],
"internalSource": "**",
"cveId": "*****",
......
}
Both the cveId and value properties are annotated with #ApiModelProperty(accessMode = ApiModelProperty.AccessMode.READ_ONLY) which means they are ignored when deserializing. Remove this annotation from both properties.

Caused by: javax.persistence.NonUniqueResultException: query did not return a unique result: 2 For Save data

I can not save Data. When I saved post request got error?
#Entity
#Table(name = "ALKP")
public class ALKP {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
#Column(name = "KEYWORD")
private String keyword;
private String code;
private Long slNo;
private String fullName;
private boolean isActive;
#CreationTimestamp
#Column(name = "created_at",updatable = false)
private LocalDate createDate;
#UpdateTimestamp
#Column(name = "updated_at")
private LocalDateTime updateDateTime;
#ManyToOne
#JoinColumn(name="parentId")
public ALKP parentId;
#OneToMany(mappedBy="parentId")
public Set<ALKP> subALKP = new HashSet<>();
Data ::
PostMan Body Request Data
{
"title": "FeMale",
"keyword": "GENDER_FEMALE",
"slNo": 2,
"active": true,
"code": "MC-00209",
"fullName": "FEMALE",
"parentId":700
}
"message": "detached entity passed to persist error in Spring Boot when consuming a rest service",
When I saved data it can not be catch Parent ALKP . I think It can be
parentId:{
"id":700
}
seems your ALKP enity have same parentId. or your defined the association mab be wrong.
#ManyToOne
#JoinColumn(name="parentId")
public ALKP parentId;
#OneToMany(mappedBy="parentId")
public Set<ALKP> subALKP = new HashSet<>();
Above both are pointng same ALKP and its Id then how can you get one and many object in same enity?

Spring JPA #ManyToOne and #OneToMany does not update all

I have two classes Post and Comment, one post can have multiple comments. So I have created my classes as follows:
Post:
#Entity
#Table(name = "posts")
public class Post extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(max = 100)
#Column(unique = true)
private String title;
#NotNull
#Size(max = 250)
private String description;
#NotNull
#Lob
private String content;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "post")
private Set<Comment> comments = new HashSet<>();
}
Comment:
#Entity
#Table(name = "comments")
public class Comment extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Lob
private String text;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "post_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
#JsonIdentityReference(alwaysAsId = true)
#JsonProperty("post_id")
private Post post;
}
Post method:
#PostMapping("/posts")
public Post createPost(#Valid #RequestBody Post post) {
return postRepository.save(post);
}
Swagger request:
{
"id": 0,
"title": "string",
"description": "string",
"content": "string",
"comments": [
{
"id": 0,
"text": "string",
"post_id": 0
}
]
}
When I do a POST using the above schema, I am expecting that hibernate will insert data in both the tables. But instead, I get below error:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for:
at [Source: (PushbackInputStream); line: 1, column: 117]Object id [1] (for `com.example.jpa.model.Post`) at [Source: (PushbackInputStream); line: 1, column: 115].]
Can someone please help me to understand this and how can I achieve my requirement?

Resources