Spring Boot multiple files upload with multiple objects - java

I need help I last time create the controller with the single file upload with an object and it's work for me like
My POJO class
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "file", "data" })
public class FileWithObject<T> {
#JsonProperty("file")
private MultipartFile file;
#JsonRawValue
#JsonProperty("data")
private T data;
}
MY REST CONTOLLER
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/singleFileUploadWithObject/{folder}",
method = RequestMethod.POST)
#ResponseBody
// api work
public String singleFileUploadWithObject(
#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,
FileWithObject rawData) {
return pingResponse;
}
My Postman result
That's all work for me. How to send the list of the objects through the postman or is possible to handle that way request like below rest controller
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/listOfObjectsWithSingleFile/{folder}", method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(
#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,
Set<FileWithObject> rawData) {
return pingResponse;
}
How to handle list of objects
[{
"file": fileobject,
"data": "zyz"
},{
"file": fileobject,
"data": "zyz"
}]
I'm trying to creating the api for this blow task

I have done this by use of Meta-Data concept there are few changes I did in controller and bean
Controller
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/listOfObjectsWithSingleFile/{folder}",
method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(
#PathVariable(name="bucket-uuid") String bucketUUId, #PathVariable(name="folder") String folder,
FileWithObject objects) { // change this Set<FileWithObject> rawData to FileWithObject objects
return pingResponse;
}
Bean
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "file", "files", "data" })
public class FileWithObject<T> {
#JsonProperty("file")
private MultipartFile file;
#JsonProperty("files")
private List<MultipartFile> files;
#JsonRawValue
#JsonProperty("data")
private T data;
// work like (meta-data)
List<FileWithObject> rawData;
// getter setter
}
Image's For Request
Note:- I'm Still looking for this issue handle this in a blow way
#RequestMapping(value="/filestore/{bucketuuid}/appsport.com/listOfObjectsWithSingleFile/{folder}", method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,Set<FileWithObject> rawData) {
return pingResponse;
}
hope it helps some one

Related

How can I add multiple files with 2 fields in Springboot

My request DTO :
#Getter
#Setter
public class FileUploadRequestDTO {
private MultipartFile fileMap;
private String filetype;
private String fileNature;
}
// Controller method
#RequestMapping(path = FLAT_FILE_UPLOAD, method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<FileUploadResponseDTO> flatFileUpload(List<FileUploadRequestDTO> fileDTO){
}
**
Question:
I want to send multiple files with the following variables in the request body. How to achieve this in Postman?
**

How to read additional JSON attribute(s) which is not mapped to a #RequestBody model object in Spring boot

I have a RestController which looks like this
#RequestMapping(value = "/post", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> test(#RequestBody User user) {
System.out.println(user);
return ResponseEntity.ok(user);
}
And the User model which looks like this
class User {
#NotBlank
private String name;
private String city;
private String state;
}
I have a requirement wherein users can pass some extra additional attribute(s) in the input JSON, something like this
{
"name": "abc",
"city": "xyz",
"state": "pqr",
"zip":"765234",
"country": "india"
}
'zip' and 'country' are the additional attributes in the input JSON.
Is there any way in Spring Boot we can get these additional attributes in the Request Body ?
I know a way wherein I can use either a "Map" or "JsonNode" or "HttpEntity" as Requestbody parameter. But I don't want to use these classes as I would loose the javax.validation that can be used inside "User" model object.
Extend your User DTO with a Map<String, String> and create a setter which is annotated with #JsonAnySetter. For all unknown properties this method will be called.
class User {
private final Map<String, Object> details= new HashMap<>);
#NotBlank
private String name;
private String city;
private String state;
#JsonAnySetter
public void addDetail(String key, Object value) {
this.details.add(key, value);
}
public Map<String, Object> getDetails() { return this.details; }
}
Now you can obtain everything else through the getDetails().

boolean is set to false if it's not present in #RequestBody

I've stumbled upon interesting case and I'm not sure how to resolve it. It's probably related to JSON Post request for boolean field sends false by default but advices from that article didn't help.
Let's say I have this class:
public class ReqBody {
#NotNull
#Pattern(regexp = "^[0-9]{10}$")
private String phone;
//other fields
#NotNull
#JsonProperty(value = "create_anonymous_account")
private Boolean createAnonymousAccount = null;
//constructors, getters and setters
public Boolean getCreateAnonymousAccount() {
return createAnonymousAccount;
}
public void setCreateAnonymousAccount(Boolean createAnonymousAccount) {
this.createAnonymousAccount = createAnonymousAccount;
}
}
I also have endpoint:
#PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<MyOutput> test(
#ApiParam(value = "information", required = true) #RequestBody ReqBody input
) {
//do something
}
problem is when I send my request body as:
{
"phone": "0000000006",
"create_anonymous_account": null
}
or just like
{
"phone": "0000000006"
}
it sets createAnonymousAccount to false.
I have checked, and it correctly recognises "create_anonymous_account": true
Is there any way to "force" null value in boolean field?
I really need to know if it was sent or no, and not to have default value.
You can use Jackson annotation to ignore the null fields. If the Caller doesn't send createAnonymousAccount then it will be null.
#JsonInclude(JsonInclude.Include.NON_NULL)
public class ReqBody {
#NotNull
#Pattern(regexp = "^[0-9]{10}$")
private String phone;
//other fields
#JsonProperty(value = "create_anonymous_account")
private Boolean createAnonymousAccount ;
}

Ignore json POJO fields not mapped in object in spring boot

I have pojo which has many fields. I have set value some field. But when i create json, whole pojo create a json . here is the code i have used:
Pojo
public class BasicInfoModel {
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
Repository code
public BasicInfoModel getBasicInfo() {
BasicInfoModel lm = new BasicInfoModel();
lm.setFather_name("Enamul Haque");
return lm;
}
Controller code
#RequestMapping(value = "/get_donar_basic_info", method = RequestMethod.POST, produces ="application/json")
public #ResponseBody BasicInfoModel getBasicinfo(){
return repository.getBasicInfo();
}
But my json is resposne like bellow:
{
"client_id": "",
"father_name": "Enamul Haque",
"mother_name": "",
"gendar": ""
}
I have set value to father_name but i have seen that i have found all the value of pojo fields. I want get only set value of father_name and ignor other value which is not set in repository.
My json look like bellow: I will display only father_name.how to display bellow like json from above code?
{
"father_name": "Enamul Haque"
}
Please help me..
Json include non null values to ignore null fields when serializing a java class
#JsonInclude(Include.NON_NULL)
Jackson allows controlling this behavior at either the class level:
#JsonInclude(Include.NON_NULL)
public class BasicInfoModel { ... }
at the field level:
public class BasicInfoModel {
private String client_id="";
#JsonInclude(Include.NON_NULL)
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
from jackson 2.0 use here use
#JsonInclude(JsonInclude.Include.NON_NULL)
You can also ignore the empty values
#JsonInclude(JsonInclude.Include.NON_EMPTY)
Add the #JsonIgnoreProperties("fieldname") annotation to your POJO.
Or you can use #JsonIgnore before the name of the field you want to ignore while deserializing JSON. Example:
#JsonIgnore
#JsonProperty(value = "client_id")
#RequestMapping(value = "/get_donar_basic_info", method = RequestMethod.POST, produces ="application/json")
public #ResponseBody BasicInfoModel getBasicinfo(){
return repository.getBasicInfo();
}
You can ignore field at class level by using #JsonIgnoreProperties annotation and specifying the fields by name:
#JsonIgnoreProperties(value = { "client_id" })
public class BasicInfoModel {
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
Or you can use #JsonIgnore annotation directly on the field.
public class BasicInfoModel {
#JsonIgnore
private String client_id="";
private String father_name="";
private String mother_name="";
private String gendar="";
//Getter and setter
}
You can read here more about this.

Managing enums with Spring Data REST

I've a project with Spring Boot 1.5.7, Spring Data REST, Hibernate, HATEOAS, Spring validation.
I'm really struggling trying to manage enums. I need two simple things:
get the list of items of a specific enum (HTTP REST)
Sent an enum as parameter into a HTTP REST calls
I'm using Spring Data REST, so a lot of the work should be made from it.
My enum is something basic like:
public enum TransitCertificateStatus {
PENDING, USED, CANCELED, ARCHIVED
}
this enum is used into a bean:
#Entity
#EntityListeners(TransitCertificateListener.class)
public class TransitCertificate extends AbstractEntity {
private static final long serialVersionUID = 5978999252424024545L;
#NotNull(message = "{NotNull.transitcertificate.status}")
#Column(nullable = false)
#Enumerated(EnumType.STRING)
private TransitCertificateStatus status = TransitCertificateStatus.PENDING;
To exposes enum items to the client I created a custom controller:
#Api(tags = "TransitCertificate Entity")
#RepositoryRestController
#RequestMapping(path = "/api/v1/transitCertificates")
public class TransitCertificateController {
private Logger log = LogManager.getLogger();
#RequestMapping(method = RequestMethod.GET, path = "/states", produces = "application/json")
public #ResponseBody ResponseEntity<?> getTransitCertificateStates() {
Resources<TransitCertificateStatus> resources = new Resources<TransitCertificateStatus>(
Arrays.asList(TransitCertificateStatus.values()));
return ResponseEntity.ok(resources);
}
This works fine, and the http response is:
{
"_embedded": {
"transitCertificateStatuses": [
"In attesa",
"Utilizzato",
"Annullato",
"Archiviato"
]
}
}
Note the items are translated because I set these values into rest-messages.properties and Spring Data REST takes care of the conversion.
server.model.enums.TransitCertificateStatus.PENDING = In attesa
server.model.enums.TransitCertificateStatus.USED = Utilizzato
server.model.enums.TransitCertificateStatus.CANCELED = Annullato
server.model.enums.TransitCertificateStatus.ARCHIVED = Archiviato
So far, everything is as expected.
Now I need to get a filtered list of by bean TransitCertificate and I am exposing directly the repository as a REST resource:
#RepositoryRestResource
#Transactional
#PreAuthorize("isAuthenticated()")
public interface TransitCertificateRepository extends PagingAndSortingRepository<TransitCertificate, Long> {
#Transactional(readOnly = true)
#Query("SELECT t FROM TransitCertificate t WHERE (:code IS NULL OR code=:code) AND (:date IS NULL OR DATE(createdDate)=DATE(:date)) AND (:text IS NULL OR text LIKE CONCAT('%',:text,'%')) AND (:from IS NULL OR t.from LIKE CONCAT('%',:from,'%')) AND (:customerName IS NULL OR customerName LIKE CONCAT('%',:customerName,'%')) AND (:states IS NULL OR status IN (:states)) ")
public Page<TransitCertificate> findAllByParameters(#Param("code") #RequestParam(value = "code", required = false) String code,
#Param("date") #RequestParam(value = "date", required = false) Instant date,
#Param("text") #RequestParam(value = "text", required = false) String text,
#Param("from") #RequestParam(value = "from", required = false) String from,
#Param("customerName") #RequestParam(value = "customerName", required = false) String customerName,
#Param("states") #RequestParam(value = "states", required = false) List<TransitCertificateStatus> states, Pageable pageable);
#Transactional(readOnly = true)
#Query("SELECT t FROM TransitCertificate t WHERE (:#{#filter} IS NULL OR t.status=:#{#filter.status}) ")
public Page<TransitCertificate> findAllByParameters2(#RequestBody #RequestParam(value="filter") #Param("filter") TransitCertificateFilter filter,
Pageable pageable);
The client sends enum translated values as the server replied in the first instance (it doesn't know anything else about the enum).
First approach
In the first approach I used a List<TransitCertificateStatus> as parameter but unfortunately I have an exception:
Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: org.springframework.hateoas.Resources["_embedded"])
So I tried a different approach.
Second approach
This time I created a bean that is the filter and contains all parameters that should be filtered in the query.
public class TransitCertificateFilter implements Serializable {
private TransitCertificateStatus status;
public TransitCertificateStatus getStatus() {
return status;
}
public void setStatus(TransitCertificateStatus status) {
this.status = status;
}
}
In the method findAllByParameters2 so I use SpEL to get the property status from the bean the client sent.
This is the request:
{
"status":"Annullato"
}
And this is the exception I've back:
{
"timestamp": "2017-10-12T15:46:20.292+0000",
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.expression.spel.SpelEvaluationException",
"message": "EL1007E: Property or field 'status' cannot be found on null",
"path": "/api/v1/transitCertificates/search/findAllByParameters2"
}
I searched for a while info about this but I didn't find anything useful. Is someone able to put me on the right path?

Categories

Resources