Is there any way to bind different query string pertaining to same field of #ModelAttribute in #Controller - spring

Class ExampleModel {
private String product;
}
#RequestMapping("/products")
public getProducts( #ModelAttribute ExampleModel model){
}
* What I want is to populate model with product class member if I hit the following REST end points:
/products?product=xyz or /products?prodName=xyz or /products?prod=xyz
*

Related

Can we Convert more than one entity into single Dto in Spring boot

Can we Convert More Than One Entity into single DTO
I have two entity Car And Truck and I want to pass single Entity VehcileDto on Thymleaf page is it possible or not?
That's not necessarily a Spring Boot topic but rather a Java topic.
Say you got the following classes:
/**
* In this class you would define the Car Entity with all its fields and relations
*/
public class CarEntity {
private String someCarField;
private String anotherCarField;
public String getSomeCarField() {
return someCarField;
}
public void setSomeCarField(String someCarField) {
this.someCarField = someCarField;
}
public String getAnotherCarField() {
return anotherCarField;
}
public void setAnotherCarField(String anotherCarField) {
this.anotherCarField = anotherCarField;
}
}
Your Truck Entity would look very similar.
Then you define a DTO:
/**
* Here you would define the DTO. The DTO is just two Entities in one WrapperObject (See Definition of DTO in Java).
* This includes all the fields you want to use on your thymeleaf UI.
* This is the DTO you would put into your model using the MVC Controller
*/
public class VehicleDTO {
private String someTruckField;
private String anotherTruckField;
private String someCarField;
private String anotherCarField;
public VehicleDTO(String someTruckField, String anotherTruckField, String someCarField, String anotherCarField) {
this.someTruckField = someTruckField;
this.anotherTruckField = anotherTruckField;
this.someCarField = someCarField;
this.anotherCarField = anotherCarField;
}
}
This is a class that contains both Entities.
Then you would need a factory to properly create the DTO:
/**
* This is a Factory class which creates a VehicleDTO
*/
public class VehicleDTOFactory {
public VehicleDTO createVehicleDTO(CarEntity car, TruckEntity truck){
return new VehicleDTO(truck.getSomeTruckField(),
truck.getAnotherTruckField(),
car.getSomeCarField(),
car.getAnotherCarField());
}
}
Then over the MVC controller you would call the factory Method and fill the parameters with Entities from your database.
This is just a very basic example.
I'd recommend looking closer into why Factories and DTOs are used

Should the shared variable inside the service that is in the mvc controller be volatile?

Inside the MVC controller , I have a service that I access to get data:
#Controller
#AllArgsConstructor
public class DataController {
private SharedDataService sharedDataHolder;
#RequestMapping(value = "/testPoint", method = GET)
public String getData(#PathVariable String point, Model model){
Data data = sharedDataHolder.getData();
...
}
}
and SharedDataService :
#Service
public class SharedDataService {
private Data data;
public Data getData(){
if(isHourAgo()){
this.refreshData();
}
return data;
...
}
}
And actually the question is, should I make the data variable of the SharedDataService class volatile so that there is no conflict inside the controller?
Data :
public class Data {
private String title;
private Map<String,Double> characteristics;
}

How to send model attribute to spring controller using Postman

I want to test my controller using postman but don't know how to send a model attribute using postman.
I tried to send all attributes in row json fornamt and x-www-form-urlencoded in body but it is not working for me, I didn't understand where i'm getting wrong
My controller class looks like :
#RestController
public class DemoController {
#Autowired
private DemoService demoService;
#RequestMapping(value = "/userDetail", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON })
public String testme(
ModelMap model,
#ModelAttribute("inputParameter") InputParameter inputParameter,
BindingResult result) {
return demoService.getDetail(inputParameter);
}
}
Model Class :
public class InputParameter {
private String id;
private String name;
private String number;
private String address;
private String pass;
}

Spring MVC multiple form backing object

Say, in request, I'm getting
?name=Jack&age=26&price=100&quantity=2
I have two model objects as below
public class User {
public String name;
public String age;
//getters and setters
}
public class Order {
public int price;
public int quantity;
//getters and setters
}
Now I want to have a controller method as below
#RequestMapping(value = "/submit", method = RequestMethod.GET)
public String home(#ModelAttribute("user") User user, #ModelAttribute("order") Order order, Model model) {
//stuff
}
As you can see I want to populate the model objects using two separate #ModelAttribute annotation. Is this possible in spring mvc?
Sattyaki, I suggest you to provide a few getters/setters to User and Order, and then compose the desired request with another class:
public class Checkout {
private User user;
private Order order;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
}
And to request for this operation, just issue a GET to the wanted URI(/submit) with your parameters. Observe that they are now using dot notation:
/submit?user.name=Jack&user.age=26&order.price=100&order.quantity=2

#PathVariable not binding with #RequestBody

When I don't use #RequestBody the #PathVariable id is automatically set at my Entity class. But if I use #RequestBody it's not. I need that the id of Entity is set before my GenericValidator executes validation. Why does it work without #RequestBody and not with it?
The Entity class:
public class Entity {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//...
}
The controller class:
#Controller
#RequestMapping(value = "/entity")
public class EntityController {
#Autowired
private GenericValidator validator;
#InitBinder
private void initBinder(WebDataBinder binder) {
binder.addValidators(validator);
}
#RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public #ResponseBody Response update(
#PathVariable String id,
#Valid #RequestBody Entity entity)
{
//...
}
}
When used alone, #Valid works much like #ModelAttribute. The Entity method argument would be retrieved from the Model or instantiated, the WebDataBinder would handle the data binding process (this is when the id would be set), and then validation would occur.
#RequestBody arguments do not go through the data binding process like #ModelAttribute arguments. They're created via an HttpMessageConverter using the body of the request instead of matching the names of request parameters and path variables to the names of your object's fields. When combined with #Valid, the configured validator is run against the new object but #ModelAttribute style data binding still does not occur.

Resources