How to set default value to a path variable? - spring

#GetMapping(value = "/{locale}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getLocale(#PathVariable("locale") String locale) {
return new ResponseEntity<>(locale, HttpStatus.OK);
}
I want if locale is null, I can set a default value "english" in it.

By default PathVariable is required but you can set it optional as :
#GetMapping(value = "/{locale}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getLocale(#PathVariable(name="locale", required=
false) String locale) {
//set english as default value if local is null
locale = locale == null? "english": locale;
return new ResponseEntity<>(locale, HttpStatus.OK);
}

You can use required false attribute and then can check for null or empty string value. Refer this thread
getLocale(#PathVariable(name ="locale", required= false) String locale
And then check for null or empty string.

You cannot provide default value to spring path variable as of now.
You can do the following obvious thing:
#GetMapping(value = "/{locale}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getLocale(#PathVariable("locale") String locale) {
locale = locale == null? "english": locale;
return new ResponseEntity<>(locale, HttpStatus.OK);
}
But more appropriate is to use Spring i18n.CookieLocaleResolver, so that you do not need that path variable anymore:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>

We can set the required property of #PathVariable to false to make it optional.
But we will also need to listen for requests that are coming without path variable.
#GetMapping(value = { "/{locale}", "/" }, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getLocale(#PathVariable("locale") String locale) {
return new ResponseEntity<>(locale, HttpStatus.OK);
}

You just need to provide default value
#GetMapping(value = "/{locale}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getLocale(#PathVariable("locale", defaultValue="english") String locale) {
return new ResponseEntity<>(locale, HttpStatus.OK);
}

Related

How do I enter path variable as UUID in postman request?

I have path variable parameter as a UUID, with path as id.
#RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
public ResponseEntity<T> getId(#PathVariable("id") final UUID id) {
}
when I add this as a String4df34f48-33ce-4da2-8eba-a682e2d1e698 or as String in brackets{4df34f48-33ce-4da2-8eba-a682e2d1e698} in my postman url, I get a 400 Bad Request error.
What can I do to add it here?
Thanks.
You need to have #PathVariable as part of the function itself:
#RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
public ResponseEntity<UUID> getUID(#PathVariable("id") final UUID id) {
log.info("id is {}", id);
return new ResponseEntity<>(id, HttpStatus.OK);
}
That should then allow you to query it through Postman:
http://localhost:8080/4df34f48-33ce-4da2-8eba-a682e2d1e698

Spring get MediaType of received body

Following this answer I've set my method in controller this way:
#PostMapping(path = PathConstants.START_ACTION, consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<BaseResponse<ProcessInstance>> start(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params)
Now I need to behave differently according to my #RequestBody being of one MediaType or the other, so I need to know whether my params body is json o urlencoded. Is there a way to do this?
You can simply inject Content-Type header.
#PostMapping(path = "/{processDefinitionId}", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> start(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params,
#RequestHeader("Content-Type") String contentType) {
if (contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
System.out.println("json");
} else {
// ...
}
return ResponseEntity.ok(params);
}
But I would suggest to split this method on two methods with different consumes values:
#PostMapping(path = "/v2/{processDefinitionId}", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> startV2Json(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params) {
return ResponseEntity.ok(params);
}
#PostMapping(path = "/v2/{processDefinitionId}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<String> startV2UrlEncoded(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params) {
return ResponseEntity.ok(params);
}

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};
}
}

#PathVariable Validation in Spring 4

How can i validate my path variable in spring. I want to validate id field, since its only single field i do not want to move to a Pojo
#RestController
public class MyController {
#RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity method_name(#PathVariable String id) {
/// Some code
}
}
I tried doing adding validation to the path variable but its still not working
#RestController
#Validated
public class MyController {
#RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity method_name(
#Valid
#Nonnull
#Size(max = 2, min = 1, message = "name should have between 1 and 10 characters")
#PathVariable String id) {
/// Some code
}
}
You need to create a bean in your Spring configuration:
#Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
You should leave the #Validated annotation on your controller.
And you need an Exceptionhandler in your MyController class to handle theConstraintViolationException :
#ExceptionHandler(value = { ConstraintViolationException.class })
#ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleResourceNotFoundException(ConstraintViolationException e) {
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
StringBuilder strBuilder = new StringBuilder();
for (ConstraintViolation<?> violation : violations ) {
strBuilder.append(violation.getMessage() + "\n");
}
return strBuilder.toString();
}
After those changes you should see your message when the validation hits.
P.S.: I just tried it with your #Size validation.
To archive this goal I have apply this workaround for getting a response message equals to a real Validator:
#GetMapping("/check/email/{email:" + Constants.LOGIN_REGEX + "}")
#Timed
public ResponseEntity isValidEmail(#Email #PathVariable(value = "email") String email) {
return userService.getUserByEmail(email).map(user -> {
Problem problem = Problem.builder()
.withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE)
.withTitle("Method argument not valid")
.withStatus(Status.BAD_REQUEST)
.with("message", ErrorConstants.ERR_VALIDATION)
.with("fieldErrors", Arrays.asList(new FieldErrorVM("", "isValidEmail.email", "not unique")))
.build();
return new ResponseEntity(problem, HttpStatus.BAD_REQUEST);
}).orElse(
new ResponseEntity(new UtilsValidatorResponse(EMAIL_VALIDA), HttpStatus.OK)
);
}

how can I pass attribute from sprint to scalate template?

I'm learning scalate template engine. How can I pass an object (for example User) from my controller to template .ssp in my scalate template ?
my controller
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! the client locale is "+ locale.toString());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
User user = new User("Dawid", "Pacholczyk");
model.addAttribute(user);
return "defaultTemplate";
}
Given the Spring support is implemented using a ViewResolver I guess you can pass parameters to it like this:
val response = new ModelAndView
response.addObject("user", new User)
return response
Have a look at the spring example as well.
Edit:
You need to return a ModelAndView like so:
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView home(Locale locale, Model model) {
...
User user = new User("Dawid", "Pacholczyk");
template = new ModelAndView("defaultTemplate");
template.addObject("user", user);
return template;
}

Resources