How to give default date values in requestparam in spring - 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

Related

Spring controller can accept ZonedDatedTime as #RequestParam but not #RequestBody

The following code works
public #ResponseBody
Map<String, Object> test(#RequestParam #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime startDate,
#RequestParam #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime endDate) {
return null;
}
with this request
https://localhost:8080/api/v1/test?startDate=2000-10-31T01:30:00.000-00:00&endDate=2000-10-31T01:30:00.000-00:00
But the following code throws exception
public #ResponseBody
Map<String, Object> test(#RequestBody #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime startDate,
#RequestBody #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime endDate) {
return null;
}
with this body
{
"endDate":"2000-10-31T01:30:00.000-00:00",
"startDate":"2000-10-31T01:30:00.000-00:00"
}
has this exception
[org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected token (START_OBJECT), expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.ZonedDateTime value; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.ZonedDateTime value
You must use #ModelAttribute or make object or map for mapping body, because Reflection utils not have opportunity for reading function parameter names (you cant specify property name for mapping).
public class User {
private String name;
private String occupation;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#RestController
public class MyController {
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/myfoo")
public void process2(#ModelAttribute("email") String email) {
}
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/vals")
public void process(#RequestBody MultiValueMap<String, String> values) {
}
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/user", consumes = MediaType.APPLICATION_JSON_VALUE)
public void process2(#RequestBody User user) {
}
}
ATTENTION
always set name of property for #RequestParam, else you can take error if somebody add not only this parameter or changed function signature

how to change the format of timestamp in springboot

I write a controller like this and it just return the current timestamp
#GetMapping(value = "/i/testTime")
Timestamp testTime(HttpServletRequest req) throws IOException {
return new Timestamp(System.currentTimeMillis());
}
I access the url and it returns:
"2022-02-25T08:23:32.690+00:00"
Is there a way to configure this format?
Any answer will be helpful
I would suggest using java.time package's LocalDateTime class.
LocalDateTime now = LocalDateTime.now();
// LocalDateTime cvDate = Instant.ofEpochMilli(milliseconds).atZone(ZoneId.systemDefault()).toLocalDateTime();
// LocalDateTime utcDate = Instant.ofEpochMilli(milliseconds).atZone(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("Before Formatting: " + now);
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String formatDateTime = now.format(format);
Output
Before Formatting: 2017-01-13T17:09:42.411
After Formatting: 13-01-2017 17:09:42
SO in your case, it would be something like this:
#GetMapping(value = "/i/testTime")
String testTime(HttpServletRequest req) throws IOException {
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
return currentDateTime.format(format);
}
You can even do it with annotations without having logic in your controller.
public class DateDto {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private LocalDateTime date;
public DateDto(LocalDateTime date){
this.date = date;
}
public LocalDateTime getDate(){
return this.date;
}
}
And your controller like:
#GetMapping(value = "/i/testTime")
DateDto testTime(HttpServletRequest req) throws IOException {
return new DateDto(LocalDateTime.now());
}

#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 provide default values for array parameters in spring MVC url mapping?

#RequestMapping(value = "/getUserScoreCardDetails", method = RequestMethod.GET)
public #ResponseBody List<ScoreDetails> getUserScoreCardDetails(
#RequestParam(value = "playerIds", required = false) int[] playerIds) {
}
I need to provide default values [1,2,3] for playerIds if playerIds is not available in request?
You can set comma separated values inside defaultValue property in #RequestParam
#RequestMapping(value = "/getUserScoreCardDetails", method = RequestMethod.GET)
public #ResponseBody List<ScoreDetails> getUserScoreCardDetails(
#RequestParam(value = "playerIds", required = false, defaultValue="1,2,3") int[] playerIds) {
}
Inside your method, just check, if playerIds is null and if it is null then specify the default values there like this
#RequestMapping(value = "/getUserScoreCardDetails", method =
RequestMethod.GET)
public #ResponseBody List<ScoreDetails> getUserScoreCardDetails(
#RequestParam(value = "playerIds", required = false) int[] playerIds) {
if(playerIds==null){
playerIds = {1,2,3};
}
}

Spring Rest Issue

I am getting an error while i am trying to test my "testCreateUser" method using Spring RestApi, the uploadNewUser.xml contains the login information about the user and the role.
#Test
public void testCreateUser() throws Exception {
Reader reader = getFileReader("src/test/resources/uploadNewUser.xml");
String input_xml = IOUtils.toString(reader);
byte[] content = input_xml.getBytes();
request.addHeader("Accept", "application/xml");
request.addHeader("Content-Type", "application/xml");
request.setContent(content);
request.setContentType("text/xml");
request.setMethod(RequestMethod.POST.name());
request.setRequestURI("/restapi/users/");
final ModelAndView mav = handle(request, response);
Map<String, Object> map = mav.getModel();
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
UserCollection collection = (UserCollection) entry.getValue();
org.springframework.validation.BindingResult.error = com.xxx.dashboard.restapi.GlobalResponse#42a4fd6d
error stack:
java.lang.ClassCastException: com.xxx.dashboard.restapi.GlobalResponse cannot be cast to com.xxx.dashboard.restapi.UserCollection
and i am getting an issue with cannot cast GlobalRespose to UserCollection. can anyone tell me where exactly i am doing is wrong? any help or pointers are most welcome thanks in advance
#Controller("userrestapi")
#RequestMapping(value = { "/restapi/users/", "/restapi/users" })
public class UserRestApi extends AbstractBaseApi {
...
#RequestMapping(method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.CREATED)
public ModelAndView createNewUser(#RequestBody UserCollection userCollection,
#RequestHeader(value = "accept", required = false) String accept,
#RequestHeader(value = "version", required = false) String version) {
try {
OOUser ooUser = userCollection.getUsers().get(0);
Mapper mapper = (Mapper) userVersions.get(Constants.USER_DETAIL_VERSION_MAPPER_KEY);
int userId = usersRestApiService.validateAndCreateNewUser(ooUser, mapper);
List<FilterField> filterFieldList = new ArrayList<FilterField>();
filterFieldList.add(new FilterField("userId", String.valueOf(userId)));
return getUserDetailsForFilter(filterFieldList, accept, version, mapper);
} catch (Exception ex) {
logger.warn("Api exception", ex);
return getModelAndView(accept, "error", getGlobalResponse(ex));
}
the abstractbaseapi contains following
public class AbstractBaseApi {
public static final String XML_VIEW = "apiXmlView";
public static final String JSON_VIEW = "apiJsonView";
public static final String JSON_ACCEPT_HEADER = "application/json";
public static final String JSON_CONTENT_HEADER = "Content-type: application/json";
public static final String XML_CONTENT_HEADER = "Content-type: text/html;charset=utf-8";
public static final int MAX_COUNT = 100;
public static final String XML_REQUEST_ERROR_FORMAT = "<?xml version='1.0' encoding='UTF-8'?><GlobalResponse xmlns='http://www.operative.com/api' xmlns:v2='http://www.operative.com/api/v2' xmlns:v1='http://www.operative.com/api/v1'> <error errorCode='%1$s' text='%2$s'/> </GlobalResponse>";
public static final String JSON_REQUEST_ERROR_FORMAT = "{error:{errorCode:'%1$s',text:'%2$s'}}";
protected final Logger logger = Logger.getLogger(this.getClass());
protected ModelAndView getModelAndView(String accept, String key, Object value) {
String view = XML_VIEW;
if (accept != null && accept.toLowerCase().contains(JSON_ACCEPT_HEADER)) {
view = JSON_VIEW;
}
if (logger.isDebugEnabled()) {
logger.debug("Accept Header:" + accept + " , generating:" + view);
}
return new ModelAndView(view, BindingResult.MODEL_KEY_PREFIX + key, value);
}
Your model contains more than you think.
You are going through your model and looking for your user collection. However, the first encountered object in your map seems to be the GlobalResponse map.
You should probably just get it by name from the model, i.e.
UserCollection collection = (UserCollection) mav.getModel().get("userCollection");
rather than iterating..

Resources