SpringBoot Define variables to use in the class - spring-boot

I have a SpringBoot project with two classes DashboardController.java and DashboardService.java. I need to define the variable that I get from the Controller to use it in the whole Service class. I explain the problem.
This is the method I have in the DashboardController.java, in which I collect by URL the variable iniDate from the front-end:
#GetMapping(path = { "/{employee_id}/{iniDate}" })
public EmployeeDashboardDto getEmployeeDashboarYearInidDto(
#ApiParam(value = "employee_id", required = true) #PathVariable("employee_id") Integer idEmployee,
#ApiParam(value = "iniDate", required = true) #PathVariable("iniDate") #DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate iniDate
) throws QOException {
return dashboardService.getEmployeeDashboardYearIniDto(idEmployee,iniDate);
}
And this is the method that I have in the DashboardService.java class in which I collect the iniDate variable from the Controller:
public EmployeeDashboardDto getEmployeeDashboardYearIniDto(Integer idEmployee, EmployeeDashboardDto iniDate) {
EmployeeDashboardDto initDate = iniDate;
return initDate;
}
I'm not sure if I collect the variable correctly, but what I need first is to collect the variable from the front-end in the controller using the URL, then collect it in the service and finally define that variable is the service to use it in the rest of the methods.

You are receiving the date in your controller and casting it as LocalDate then your method in the service class needs to receive the date in the same type LocalDate.
Change the parameter type to LocalDate like this:
public EmployeeDashboardDto getEmployeeDashboardYearIniDto(Integer idEmployee, LocalDate iniDate) {
EmployeeDashboardDto employeeDashboardDto = new EmployeeDashboardDto();
employeeDashboardDto.setIniDate(iniDate);
return employeeDashboardDto;
}
If you need to receive dates as PathVariables you can check this or this answer.

I have created the following method in the DashboardService.java I have changed the name of the initDate variable:
public EmployeeDashboardDto getEmployeeDashboardYearIniDto(Integer employeeId, LocalDate iniDate) {
EmployeeDashboardDto initDate = new EmployeeDashboardDto();
initDate.setIniDate(iniDate);
return initDate;
}
And in the Dto I have created the following method:
public void setIniDate(LocalDate iniDate) {
// TODO Auto-generated method stub
}
But in the Service, in the methods that is used the initDate variable says that initDate cannot be resolved to a variable

Related

Spring's Request Parameter retrieve value and validation

I have a simple Spring Boot application which accepts various event types. I have put a validation on the controller to check against those Event types. If Event Type does not match the Enum from the calling Client App, i throw an exception. However if the Value matches one of the event i want to retrieve that value and do a custom logic from Controller to Service Class. Any idea on how it can be done. Here is the Rest Controller and Enum Class.
public enum EventTypes {
ADDONE("AddOne"),
DELETEONE("DeleteOne"),
ADDTWO("AddTwo"),
DELETETWO("DeleteTwo");
private String event;
private EventTypes(String event){
this.event = event;
}
}
Rest Controller:
#PostMapping(value = "/eventProcess", consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public GenericResponse produceEventMessage(
#Parameter(in = ParameterIn.QUERY, description = "", required = true)
#RequestParam(value = "eventType", required = true) EventTypes eventType,
#Valid #RequestBody MessageRequest messageEventRequest) {
LOG.info("Event Type ::::" + eventType); // I need to retrieve this value
... Remaining Business Logic to be executed
}
Client Application URL : http://localhost:8080/eventProcess?eventType=AddOne

How can I get "id" dynamically to set an object

Well, inside getOne() I'm forcing an id I used for testing. I need, dynamically, to inform which id inGuiaRecolhimento I will set in PagamentoGuia. How could I do it?
#PostMapping
public PagamentoGuia create(#RequestBody PagamentoGuia pagamentoGuia) {
GuiaRecolhimento g = repositoryGuia.getOne((long) 764);
pagamentoGuia.setGuia(g);
return repository.save(pagamentoGuia);
}
IMHO you'll have to create a DTO which receives the GuiaRecolhimento's id.
Since you're creating a PagamentoGuia in your database, receiving the id of GuiaRecolhimento as Path Variable is not appropriated, since it's not related to the main collection we are referring to (PagamentoGuia).
Use DTO's. That way you follow the correct semantic according to REST patterns.
Receive the id in the PostMapping url whith a PathVariable.
#PostMapping(value = "/{id}")
public PagamentoGuia create(#RequestBody PagamentoGuia pagamentoGuia, #PathVariable(value = "id") Long id) {
GuiaRecolhimento g = repositoryGuia.getOne(id);
pagamentoGuia.setGuia(g);
return repository.save(pagamentoGuia);
}
Edit:
I agree with Matheus Cirillo
For you follow the correct semantic according to REST patterns you can use a DTO object.
public class PagamentoGuiaDto {
private Long guiaRecolhimentoId;
// all attributes of PagamentoGuiaDto
// all getters and setters
}
#PostMapping
public PagamentoGuia create(#RequestBody PagamentoGuiaDto dto) {
GuiaRecolhimento g = repositoryGuia.getOne(dto.getPagamentoGuiaId());
PagamentoGuia pagamentoGuia = new PagamentoGuia();
pagamentoGuia.setGuia(g);
// set the values of dto to pagamentoGuia
return repository.save(pagamentoGuia);
}

Spring Boot/Java Mapping Enum Values to RequestParam [duplicate]

This question already has answers here:
Spring's #RequestParam with Enum
(9 answers)
Closed 3 years ago.
I have an Enum like below
public enum Customer {
RETAIL("retail"),
FREELANCER("FreeLancer"),
MARKET("market"),
PUBLICATION("publication");
private String contentType;
private static final Map<String,Customer> contentTypeMap;
public String getContentType(){
return this.contentType;
}
static {
Map<String,Customer> map = new ConcurrentHashMap<>();
for(Customer type : Customer.values ()){
map.put (type.getContentType (),type);
}
contentTypeMap = map;
}
Customer(String contentType){
this.contentType=contentType;
}
public static Customer getContentType(String contentType){
return contentTypeMap.get (contentType);
}
}
This enum represents the type of customer.
We have an API that return the customer details
#RequestMapping(value="/getData", method=RequestMethod.GET, produces="application/json")
public BatchResponse triggerBatchJob(
#RequestParam(value="updateFrom", required=false) #DateTimeFormat(pattern="yyyyMMdd") String updateFrom,
#RequestParam(value="updateTo", required=false) #DateTimeFormat(pattern="yyyyMMdd") String updateTo,
#RequestParam(value="customerType") (VALIDATE_HERE)String customerType) {
// ...
}
I need to validate the customerType value to be the ones present in the Enum, Is there a way to validate the same with the method declaration as I have done in the case of date rather than method body by using getContentType method or something.
Please help.
Change your method to following:
#RequestMapping(value="/getData", method=RequestMethod.GET, produces="application/json")
public BatchResponse triggerBatchJob(
#RequestParam(value="updateFrom", required=false) #DateTimeFormat(pattern="yyyyMMdd") String updateFrom,
#RequestParam(value="updateTo", required=false) #DateTimeFormat(pattern="yyyyMMdd") String updateTo,
#RequestParam(value="customerType") CustomerType customerType) {
// ...
}
i.e. customerType type should be CustomerType not String. Now only values those match enum will be mapped.
Note:- The values will have to be provided is specific format i.e. enum name itself e.g. in your case FREELANCER,RETAIL, PUBLICATION etc values should be passed in request.
Edit
As requested by OP below is customizing the enum handling from String:
Add #initBinder in the controller and add following method:
#InitBinder
public void initBinder(final WebDataBinder webdataBinder) {
webdataBinder.registerCustomEditor(Customer.class, new CustomerConverter());
}
and declare a converter class as below:
import java.beans.PropertyEditorSupport;
public class CustomerConverter extends PropertyEditorSupport{
public void setAsText(final String text) throws IllegalArgumentException {
System.out.println("--->"+Customer.getContentType(text));
setValue(Customer.getContentType(text));
}¡¡
}
Added System.out.println to show that value is interpreted and printed as expected.
A simple null check will do
Customer customer = Customer.getContentType(customerType);
if (customer == null) {
throw new Exception("Invalid Customer type");// use validation exception
}

How to get Custom object in java spring?

I'm using java spring for my server.
My question is how can I get custom object through the controller.
Example for what I mean:
I know I can do that by doing two functions:
#RequestMapping(
path = arrayOf("getObject", "getObject/"),
method = arrayOf(RequestMethod.GET))
open fun getRecord1(#RequestBody data: CustomObjectOption1): ResponseEntity<*> {
return ResponseEntity<Any>(data.name,HttpStatus.OK)
}
#RequestMapping(
path = arrayOf("getObject", "getObject/"),
method = arrayOf(RequestMethod.GET))
open fun getRecord2(#RequestBody data: CustomObjectOption2): ResponseEntity<*> {
return ResponseEntity<Any>(data.number,HttpStatus.OK)
}
but I want to do it by only one endpoint:
#RequestMapping(
path = arrayOf("getObject", "getObject/"),
method = arrayOf(RequestMethod.GET))
open fun getRecord(#RequestBody data: CustomObjectOption): ResponseEntity<*> {
if(data instance option1)
return ResponseEntity<Any>(data.name,HttpStatus.OK)
else
return ResponseEntity(data.number,HttpStatus.OK)
else
}
such that the object can be like this:
option 1:
public class CustomObject {
private String name;
private Long id;
}
or option 2:
public class CustomObject {
private List<Integer> number;
private List<Long> count;
}
Is that possible to do that in java spring?
The only solution I was thinking is to use inheritance but I would like to know if there's different way...
Thank you for the help
Just as you have written, you can do it just like that:
#RequestMapping(...)
public void method(#RequestBody YourCustomClass body)
YourCustomClass can be either option 1 or option 2.
And that's all :)

DTO has only null with GET request params, but not POST #RequestBody

I'm trying to get my query params in a DTO like in this question but my DTO has always null value.
Is there anything wrong in my code ? I made it as simple as possible.
Queries:
GET http://localhost:8080/api/test?a=azaz => null
POST http://localhost:8080/api/test with {"a":"azaz"} => "azaz"
Controller with a GET and a POST:
#RestController
#RequestMapping(path = {"/api"}, produces = APPLICATION_JSON_VALUE)
public class MyController {
// GET: dto NOT populated from query params "?a=azaz"
#RequestMapping(method = GET, path = "test")
public #ResponseBody String test(TestDto testDto){
return testDto.toString(); // null
}
// POST: dto WELL populated from body json {"a"="azaz"}
#RequestMapping(method = POST, path = "test")
public #ResponseBody String postTest(#RequestBody TestDto testDto){
return testDto.toString(); // "azaz"
}
}
DTO:
public class TestDto {
public String a;
#Override
public String toString() {
return a;
}
}
Thanks !
Full Spring boot sample to illustrate it
The problem is that you are missing setter for the field.
public void setA(String a) {
this.a = a;
}
should fix it.
I'm assuming that you have done required configuration like having Jackson mapper in the class path, consume json attribute, getter and setter in DTO classes etc.
One thing missed here is, in RequestMapping use value attribute instead of path attribute as shown below
#RequestMapping(method = POST, value= "/test", consumes="application/json")
public #ResponseBody String postTest(#RequestBody TestDto testDto){
return testDto.toString();
}
And, make sure that you set content-type="application/json" while sending the request
I think what you are trying to do is not possible. To access the query Parameter you have to use #RequestParam("a"). Then you just get the String. To get your object this way you have to pass json as Parameter. a={"a":"azaz"}
Kind regards

Resources