Spring boot test for Restful POST API DTO with MultiPartFile attribute - java

I have a Spring Boot app which has a RestController with the following POST method:
#PostMapping(path = "/add", headers = {"content-type=multipart/form-data; charset=utf-8"})
public ResponseEntity<UserWebDTO> addUser(#RequestHeader HttpHeaders headers, #ModelAttribute UserAddDTO userAddDTO) throws Exception {
return new ResponseEntity<>(userService.addUser(userAddDTO), HttpStatus.CREATED);
}
and UserAddDto is as follows:
public class UserAddDTO {
private String first_name;
private String last_name;
private String country_code;
private String phone_number;
private GenderEnum gender;
private String birthdate;
private MultipartFile avatar;
private String email;
}
The code works fine from postman, but I have no idea how to make an integration test with MockMvc for this dto with Multipartfile object, and the test I tried gives me :
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.user.basic.authentication.dtos.UserAddDTO["avatar"]->org.springframework.mock.web.MockMultipartFile["inputStream"])
any help is appreciated.
Thanks!

I believe that you need to implements Serializable
public class UserAddDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String first_name;
private String last_name;
private String country_code;
private String phone_number;
private GenderEnum gender;
private String birthdate;
private MultipartFile avatar;
private String email;
}

Related

how to ignore response fields dynamically in spring webflux

I have the below response modal generated from swagger2.0.
Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-08-17T22:02:01.513781100-05:00[America/Chicago]")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#JsonProperty("id")
private String id;
#JsonProperty("name")
private String name;
#JsonProperty("city")
private String city ;
#JsonProperty("dateOfBirth")
private String dateOfBirth;
}
when the get User returns the response I would like to skip/Ignore the name and city and wants to return only id and dateOfBirth, how to use JsonIgnoreProperties while converting the response to bodyToMono.
public Mono<User> getUser(String userid) {
return this.webClientConfig
.getWebClient()
.get()
.uri(uriBuilder -> uriBuilder.path("/users/").path(userid).build())
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(User.class)
}
used Jackson2ObjectMapperBuilder
https://www.baeldung.com/jackson-deserialize-json-unknown-properties

Spring Boot, How to Validation (#Notblank) json array in request

Hi everyone I have a question about validate json array request in Spring Boot
This controller
public ResponseEntity<BaseResponse> humanController(#RequestHeader Map<String, String> header,#Valid #RequestBody jsonRequest rqBody) throws ServiceException,Exception {
...
...
}
This jsonRequest Model Request
public class jsonRequest {
#NotBlank
#JsonProperty(value = "name")
private String name;
#NotBlank
#JsonProperty(value = "body")
private bodyModel[] body;
...
...
}
This bodyModel Request
public class bodyModel {
#NotBlank
#JsonProperty(value = "hands")
private String hands;
#NotBlank
#JsonProperty(value = "legs")
private String legs;
#NotBlank
#JsonProperty(value = "head")
private String head;
...
...
}
How can I validate (#Notblank) in bodyModel, I use #NotBlank It not work ?

Spring Boot Request body validation on same DTO used for different API

In my request body DTO, I want specific fields to be required for one of the API but not for another.
My request body:
#Data
class MyClass {
#NotNull
private String fullName;
#NotNull
private String firstName;
#NotNull
private String lastName;
}
I want fullName to be required for /api/v1 but not for /api/v2. I am using #Valid on request body from javax.validation.
You have to use Spring's #Validated, which is a variant of JSR-303's #Valid. This is used at the method-level:
Controller:
#RequestMapping(value = "apiV1Method")
public String apiV1Method(#Validated(Account. ValidationAPI1.class) MyClassDTO myClassDTO) {...}
#RequestMapping(value = "apiV2Method")
public String apiV2Method(#Validated(Account. ValidationAPI2.class) MyClassDTO myClassDTO) {...}
Object:
class MyClassDTO {
public interface ValidationAPI1 {}
public interface ValidationAPI2 {}
#NotNull(groups = {ValidationAPI1.class})
private String fullName;
#NotNull(groups = {ValidationAPI1.class, ValidationAPI2.class})
private String firstName;
#NotNull(groups = {ValidationAPI1.class, ValidationAPI2.class})
private String lastName;
...
}

Java object not populated from json request for inner class

Have searched in different sites but couldn't find correct answer, hence posting this request though it could possible duplicates.sorry for that.
I am sending the below json request to my back-end service and converting to java object for processing. I can see the request body passed to my service but when i convert from json to java object , values are not populating
{
"data":{
"username":"martin",
"customerId":1234567890,
"firstName":"john",
"lastName":"smith",
"password":"p#ssrr0rd##12",
"email":"john.smith#gmail.com",
"contactNumber":"0342323443",
"department":"sports",
"location":"texas",
"status":"unlocked",
"OrderConfigs":[
{
"vpnId":"N4234554R",
"serviceId":"connectNow",
"serviceType":"WRLIP",
"ipAddress":"10.101.10.3",
"fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
"timeout":1800,
"mapId":"test_map"
}
]
}
}
My Parser class have something like,
JSONObject requestJSON = new JSONObject(requestBody).getJSONObject("data");
ObjectMapper mapper = new ObjectMapper();
final String jsonData = requestJSON.toString();
OrderDTO mappedObject= mapper.readValue(jsonData , OrderDTO .class);
// I can see value coming from front-end but not populating in the mappedObject
My OrderDTO.java
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true,value = {"hibernateLazyInitializer", "handler", "created"})
public class OrderDTO {
private String username;
private long customerId;
private String source;
private String firstName;
private String lastName;
private String email;
private String contactNumber;
private String password;
private String department;
private String location;
private String status;
private List<OrderConfig> OrderConfigs;
#JsonInclude(value = Include.NON_NULL)
public class OrderConfig {
private String vpnId;
private String serviceId;
private String serviceType;
private String ipAddress;
private String mapId;
private String[] fRoutes;
private Map<String, Object> attributes;
private SubConfig subConfig;
private String routeFlag;
getter/setters
.....
}
all setter/getter
}
Not sure what I'm missing here. Is this right way to do?
If your are trying to use inner class, correct way to use is to declare it static for Jackson to work with inner classes.
For reference check this
code changes made are
#JsonInclude(value = Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
static class OrderConfig {
Make sure that your json tag names match with variable names of java object
Ex : "fRoute":[
"10.255.253.0/30",
" 10.255.254.0/30"
],
private String[] fRoutes;
OrderConfigs fields will not be initialized, just modify your bean as
#JsonProperty("OrderConfigs")
private List<OrderConfig> orderConfigs;
// setter and getter as setOrderConfigs / getOrderConfigs
See my answer here. (same issue)

List of Pojo not getting converted into Json using #ResponseBody

I have controller class as below:
#RequestMapping(value = "/Reporting/FilterAsJson", method = RequestMethod.POST)
public #ResponseBody PagedQueryResult<GetEntitlementOverviewReportResult> filterAsJson(#ModelAttribute GetEntitleReportQuery query, HttpSession session)
{
getEntitlementOverviewFromSession(session).updateFromQuery(query, session);
return queryDispatcher.dispatch(query);}
The POJO class GetEntitlementOverviewReportResult is :
public class GetEntitlementOverviewReportResult
{
private Long id;
private String customerName;
private Long customerId;
private String customerNumber;
private String createdOn;
private String itemCreationDate;
private String licenseStatus;
private String licenseType;
private String licenseStatusCode;
private String licenseID;
private Long requestId;
private String licenseRootID;
private String customerNameCS;
private String customerNumberCS;
// <with getters and setters for the variables>
}
The problem is when all the fields in bean class is being set, proper Json is getting returned as a response. But when only first 6 fields are getting set, the response fails with 500 error in the debugger tool and doesn't return back to the calling ajax method. I get an "internal error" pop up in the browser. What am i missing here? Is is not possible to leave out the other fields whose values are not being fetched? I also tried using #JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) but it doesn't make any difference.

Categories