startDate comes before endDate in swagger Is there any way to preserve the order, or even specify the order - spring-boot

Actual Result: endDate comes first then startDate comes next.
Expected Result: startDate comes first then endDate.
Is there any way to specify the requestParameter order?
This is the Actual Result
public ResponseEntity<ByteArrayResource> getDetails(
#NotEmpty(message = UIMessages.MUST_NOT_BE_EMPTY) #RequestParam(
value = "startDate") final String startDate,
#NotEmpty(message = UIMessages.MUST_NOT_BE_EMPTY) #RequestParam(
value = "endDate") final String endDate,
final HttpServletRequest request) throws IOException {
//statements
}
This is the swagger UI actual result

Related

Springboot #RequestParam parameter value from possible values

I am using #RequestParam to get the column name against which I want to sort my results.
public ResponseEntity<Map<String, Object>> method(#PathVariable("tenant_id") Integer tenantId,
#PathVariable("asset_location_id") Integer assetLocationId,
#RequestParam(defaultValue = "") String search_keyword,
#RequestParam(defaultValue = "0") int page,
#RequestParam(defaultValue = "10") int size,
#RequestParam(defaultValue = "asset_name") String sort_field,
#RequestParam(defaultValue = "asc") String sort_dir) {}
How I can make sure sort_field has the only possible column names which are possible in a given response?

better way to POST multipart files with JSON data springboot

I am working on a spring boot project, I have a customer model which consists of properties, including image paths which I am storing in the file system or folder and uploading the entire form with image paths in DB, I have successfully implemented my target task however I was wondering if there is a better and nicer way to achieve this, your answers, comments, and feedbacks are appreciated here is my code
Customer model:
public class Customer {
private String contactMode = "Mobile Number";
#Pattern(regexp ="(251|0)[0-9]{9}" , message = "Invalid phone number")
private String phoneNumber; // phone number
private String identityType = "101-ID [0]";
#NotNull(message = "ID number is required")
private String idNumber;
private String countryOfIssue = "XXXXXXX";
#NotNull(message = "Issue date is required")
#PastOrPresent(message = "Issue date cannot be future date")
private Date issueDate;
#Future(message = "Expiry date cannot be in the past or present")
#NotNull(message = "Expiry date is required")
private Date expiryDate;
// storing customerImage , customerID and customerSignature paths in DB
private String customerImage;
private String customerID;
private String customerSignature;
}
Customer Service:
private String path = "C:\Users\User\Desktop\docs\uploaded_files\";
public Customer saveCustomer(Customer customer, MultipartFile customerImage, MultipartFile customerID,
MultipartFile customerSignature) throws Exception {
final String PATH = path + customer.getContactDetail();
Customer phoneNumberExists = customerRepository.findByContactDetail(customer.getContactDetail());
byte[] imageBytes = customerImage.getBytes();
byte[] idBytes = customerID.getBytes();
byte[] signatureBytes = customerSignature.getBytes();
Path customerImagePath = Paths.get
(PATH + "_photo_" + customerImage.getOriginalFilename());
Files.write(customerImagePath, imageBytes);
Path customerIDPath =
Paths.get(PATH + "_ID_" + customerID.getOriginalFilename());
Files.write(customerIDPath, idBytes);
Path customerSignaturePath =
Paths.get(PATH + "_Sign_" + customerSignature.getOriginalFilename() + "");
Files.write(customerSignaturePath, signatureBytes);
if (phoneNumberExists != null) {
throw new PhoneNumberTakenException("Phone number is taken ");
}
customer.setAge(new Date().getYear() - customer.getDateOfBirth().getYear());
customer.setCustomerImage(String.valueOf(customerImagePath));
customer.setCustomerID(String.valueOf(customerIDPath));
customer.setCustomerSignature(String.valueOf(customerSignaturePath));
customer.setFromDate(LocalDate.now());
customer.setStatus(Customer.Status.Submitted);
Customer customerRecord = customerRepository.saveAndFlush(customer);
return customerRecord;
}
Customer Controller : look at how iam passing multipart files and other fields in the controller to service
#PostMapping()
public ResponseEntity<Customer> createCustomer(#Valid #RequestPart("customer") String customer, MultipartFile customerImage, MultipartFile customerID, MultipartFile customerSignature
) throws Exception {
ObjectMapper customerMapper = new ObjectMapper();
Customer savedCustomer = customerMapper.readValue(customer, Customer.class);
Customer customerRecord = customerService.saveCustomer(savedCustomer, customerImage, customerID, customerSignature);
log.debug("inside createCustomer() controller : {}", customerRecord);
return ResponseEntity.status(HttpStatus.CREATED).body(customerRecord);
}
Postman post request to the endpoint:
Postman response :

#requestparam value = date spring boot

#Controller
#RequestMapping(value="/reservations")
public class ReservationController {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
#Autowired
private ReservationService reservationService;
#RequestMapping(method = RequestMethod.GET)
public String getReservation(#RequestParam(value="date", required=false) String dateString, Model model){
Date date = null;
if(dateString != null){
try {
date = DATE_FORMAT.parse(dateString);
} catch (ParseException pe) {
date = new Date();
}
}else{
date = new Date();
}
List<RoomReservation> roomReservationList = this.reservationService.getRoomReservationsForDate(date);
model.addAttribute("roomReservations", roomReservationList);
return "reservations";
}
}
I understand that the #RequestParam annotation is used to bind parameter values of query string to the controller method parameters. So for example, http://localhost:8080/reservations?date=2017-01-01. However, where does the value="date" come from? I dont see any value "date" inside my html page.
if you submit a form as method:"GET" (not POST) and form contains a input field named date then submitting this form will hit this handler method.

How to give default date values in requestparam in spring

#RequestMapping(value = "/getSettlements", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
Collection<Settlement> getSettlements
(#RequestParam(value = "startDate") String startDate,
#RequestParam(value = "endDate") String endDate,
#RequestParam(value = "merchantIds", defaultValue = "null") String merchantIds)
How to give today's date in defaultValue ? It only takes constant.
#InitBinder
public void initBinder(WebDataBinder binder) throws Exception {
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
final CustomDateEditor dateEditor = new CustomDateEditor(df, true) {
#Override
public void setAsText(String text) throws IllegalArgumentException {
if ("today".equals(text)) {
setValue(new Date());
} else {
super.setAsText(text);
}
}
};
binder.registerCustomEditor(Date.class, dateEditor);
}
#RequestParam(required = false, defaultValue = "today") Date startDate
If you are using LocalDate, you can create a default value like this:
#RequestParam(name = "d", defaultValue = "#{T(java.time.LocalDate).now()}", required = true) LocalDate d)
I tried pretty much every option, even using interceptors. But from far the easiest solution was to use SpEL. For Example: defaultValue = "#{new java.util.Date()}"
Since you receive a string you can any date format you want and later on use formatting to extract the date

Use a custom deserializer only on certain fields?

With gson, is it possible to use a custom deserializer / serializer only on certain fields? The user guide shows how to register an adapter for an entire type, not for specific fields. The reason why I want this is because I parse a custom date format and store it in a long member field (as a Unix timestamp), so I don't want to register a type adapter for all Long fields.
Is there a way to do this?
I also store Date values as long in my objects for easy defensive copies. I also desired a way to override only the date fields when serializing my object and not having to write out all the fields in the process. This is the solution I came up with. Not sure it is the optimal way to handle this, but it seems to perform just fine.
The DateUtil class is a custom class used here to get a Date parsed as a String.
public final class Person {
private final String firstName;
private final String lastName;
private final long birthDate;
private Person(String firstName, String lastName, Date birthDate) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDate = birthDate.getTime();
}
public static Person getInstance(String firstName, String lastName, Date birthDate) {
return new Person(firstName, lastName, birthDate);
}
public String toJson() {
return new GsonBuilder().registerTypeAdapter(Person.class, new PersonSerializer()).create().toJson(this);
}
public static class PersonSerializer implements JsonSerializer<Person> {
#Override
public JsonElement serialize(Person person, Type type, JsonSerializationContext context) {
JsonElement personJson = new Gson().toJsonTree(person);
personJson.getAsJsonObject().add("birthDate", new JsonPrimitive(DateUtil.getFormattedDate(new Date(policy.birthDate), DateFormat.USA_DATE)));
return personJson;
}
}
}
When the class is serialized, the birthDate field is returned as a formatted String instead of the long value.
Don't store it as a long, use a custom type with a proper adapter. Inside your type, represent your data any way you want -- a long, why not.

Resources