I'm working on the Spring application with Angular frontend. I'm trying to send a POST request to update data in the database but there is an exception:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot
construct instance of UpdateRecipesDTO
There is the DTO class that I receive from the frontend part:
#Data
public class UpdateRecipesDTO {
private String query;
private String meal;
private String dish;
private String cuisine;
}
And it goes to the controller method
#PostMapping(value = "/recipe-update")
public int updateByAdmin(HttpServletRequest request, #RequestBody UpdateRecipesDTO updateRecipesDTO) {
System.out.println("You're here");
}
Now the only that I want is a printed string but it doesn't print anything. I had tried to use #AllArgsConstructor Lombok annotation, but it didn't work. Writing AllArgsConstructor by myself didn't help also. So what should I do?
Related
I am developing a Java backend application using Spring Boot. My controller needs to receive this type of object as input with an HTTP POST call:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class Input {
private String name;
private String surname;
private String fiscalCode;
}
obviously these data arrive thanks to a JSON made like this:
{
"name":"John",
"surname":"Smith",
"fiscalCode":"XXXXXXXXX"
}
This is an example of a controller handling POST containing this body:
#PostMapping(produces = { "application/json" })
public ResponseEntity<Object> myController(#RequestBody Input myInput) {
// code....
}
The question is: how can I elegantly (without using a switch case or a series of if-else) detect all fields that are "" or null in my myInput object, and return a string that warns for example that "name, surname fields missing"?
What is the best way to do this? I've heard it's okay to use #ControllerAdvice, but I don't know how to do it.
Check out the #Validate annotation.
e.g. https://www.baeldung.com/spring-boot-bean-validation
I'm stuck with unit testing of rest controller which has post method
which is accepting a RequestBody of java object which contains the multipart file.
various options I search for shows how to send a single file along with request or making them as part.
is there a way to test the whole object as single entity.
Model class
#Data
public class Person{
private String name;
private String age;
private List<MultipartFile> images;
}
and the rest controller to handle the request is
Rest Controller
#RestController
#RequestMapping("/v1)
public class PersonRestController{
#Autowired
private IPersonService personService;
#PostMapping("/save")
public ResponseEntity<String> savePerson(#ModelAttribute Person person){
String name = personService.savePerson(person);
return new ResponseEntity<String>(name,HttpStatus.CREATED);
}
}
will be really helpful if anyone could help.
I am using spring-data-elasticsearch for crud operations in elastic-search.
Only able to save data to elastic-search and findById method is working.
findAll and findBy... method is not working, and giving empty response.
I tried with some other versions in POM
After some debugging i found that findById method is actually sending a HTTP GET request, and findAll/findBy... is sending HTTP POST request.
In both the cases GET/POST elastic-search is returning the response with data, that i verified on wireshark. which was running on local.
I can see the hits in response of findAll method call, on wireshark but that hits we i am not receiving via repository.
If i can see the response with data, that means elastic-search and query creation is fine, but the problem is with consuming the data in JPA. JPA is actually handling the consumption thing.
I don't have any idea about how to debug further.
Data Model Class
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Document(indexName = "data", type = "_doc")
public class Data {
#Id
private String id;
private String title;
#Field(type = FieldType.Text)
private Status status;
private String description;
}
Repository Class
#Repository
public interface DataRepository extends ElasticsearchRepository<Data,String> {
default <S extends Data> S saveWithKafkaPush(S s){
S s1 = save(s);
KafkaProducer.produceMessage(s);
return s1;
}
default <S extends Data> Iterable<S> saveAllWithKafkaPush(Iterable<S> iterable){
Iterable<S> s = saveAll(iterable);
return s;
}
Optional<Data> findByStatus(Status status);
}
Status Enum
public enum Status {
UNTITLED,
DRAFT,
REVIEW,
APPROVED,
PUBLISHED;
}
Service Class
#Autowired
private DataRepository dataRepository;
public Data findByStatus(Status status){
Optional<Data> data = dataRepository.findByStatus(status);
return data.isPresent()? data.get() : null;
}
public Data save(Data data){
return dataRepository.save(data);
}
public void deleteData(String id){
dataRepository.deleteById(id);
}
findByStatus method is not working but save and deleteData is working fine.
I'm using Angular 8 to make HTTP POST request to my Java Spring backend.
POST request in Angular 8 snippet:
...
export class TechniqueComponent implements OnInit {
constructor() { }
techniqueInfo: TechniqueInfo = new TechniqueInfo("Gogoplata",{id:1,creatorName:"Kawaishi"},1899,1969);
postTechnique(){
this.httpClient.post(`http://localhost:8081/api/TechniqueInfo`, this.techniqueInfo).subscribe((data)=>{
console.log(data);
});
}
}
In my back-end, I am correctly getting the "Gogoplata", "Kawaishi", 1899, and 1969 -- however I am always getting "id" (within that nested object) as 0.
Java (Spring) backend snippet (TechniqueInfo entity class):
#Entity
#Table(name="techniqueinfo")
public class TechniqueInfo implements Serializable {
public TechniqueInfo(){}
#Id
#Column(name="techniquename")
private String techniquename;
#OneToOne
#JoinColumn(name="techniqueid")
private Technique techniqueid;
#Column(name="birthyear")
private int birthyear;
#Column(name="deathyear")
private int deathyear;
Here is the corresponding Technique entity class for the "private Technique techniqueid":
#Entity
#Table(name = "techniquelist")
public class Technique implements Serializable {
public
#Id
#Column(name="id")
private int id;
#Column(name="creatorName")
private String creatorName;
In my TechniqueInfo (Angular) class:
export class TechniqueInfo{
constructor(
public techniquename: string,
public techniqueid: Object,
public birthyear: number,
public deathyear: number
){}
}
Here is the MVC controller for handling the POST request:
#RestController
#RequestMapping("/api/TechniqueInfo")
#CrossOrigin // allows requests from all domains
public class TechniqueInfoController {
#Autowired
private TechniqueInfoService service;
#RequestMapping(method = RequestMethod.POST)
public void addTechniqueInfo(#RequestBody TechniqueInfo tech){
service.createTechniqueInfo(tech);
};
I believe the problem may be how I am passing in the POST request object.
techniqueInfo: TechniqueInfo = new TechniqueInfo("Gogoplata",{id:1,creatorName:"Kawaishi"},1899,1969)
I am passing in an object ({id:1, creatorName:"Kawaishi"}) within the POST request body incorrectly, which is why Spring is returning me id as 0 instead of 1, even though it is returning creatorName correctly?
I am struggling to know what to pass instead of that object to make id set correctly in the Spring backend.
So I'm developping some microservices in JAVA using Spring Boot and I'm facing some problems involving the objects I'm using.
So I have a data service which is the DB interface and a scheduling service which will be called by the frontend.
Both work with their own Response and Request objects eventhough at this point they are basically the same.
please ignore that there are no getters and setters in the code below.
Data-Service
#RestController
#RequestMapping("")
public class DataServiceResource {
#GetMapping(...)
public ResponseEntity<JobDetailsResponse> getJobDetailsSingleDate(#PathVariable("singledate") final String date) {
...
return response;
}
}
JobDetailsResponse
#JsonIgnoreProperties(ignoreUnknown = true)
public class JobDetailsResponse {
private Object requestSent;
private List<Job> jobsFound;
private boolean hasError;
private String errorMessage;
private LocalDateTime dataTimestamp;
}
JobDetailsSingleDateRequest
#JsonIgnoreProperties(ignoreUnknown = true)
public class JobDetailsSingleDateRequest {
private String dateFrom;
}
Scheduling Service
#RestController
#RequestMapping("")
public class SchedulingServiceResource {
...
#Autowired
private RestTemplate restTemplate;
#GetMapping(...)
public ResponseEntity<ReportDetailsResponse> getReportDetailsSingleDate(#PathVariable("singledate") final String singledate) {
ResponseEntity<ReportDetailsResponse> quoteResponse = this.restTemplate.exchange(DATA_SERVICE_JOB_DETAILS_SINGLE_DATE_URL + singledate, HttpMethod.GET,
null, new ParameterizedTypeReference<ReportDetailsResponse>() {});
...
return response;
}
ReportDetailsSingleDateRequest
#JsonIgnoreProperties(ignoreUnknown = true)
public class ReportDetailsSingleDateRequest {
private String dateFrom;
}
ReportDetailsResponse
#JsonIgnoreProperties(ignoreUnknown = true)
public class ReportDetailsResponse {
private Object requestSent;
private List<Job> jobsFound;
private boolean hasError;
private String errorMessage;
private LocalDateTime dataTimestamp;
}
So when I go through the quoteResponse.getBody().getJobsFound() method to check the data I got from the Data Service My List of jobs is empty.
I read that If the objects are equal in definition, spring would use reflection to pass the values, but in my case its not woking.
Is there a way to consume the microservice without having to add the data service dependency to the scheduling service?
Sorry for the long post but, until now I haven't found a proper example for my case. All the examples I found work with List as return of the microservice.
Thanks in advance.