Problem in converting Java Object to JSON in Spring Boot - java

I have started with Spring Boot recently. I am facing issues while converting my Java Object to JSON in the desired format.
package com.we.springmvcboot.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.we.springmvcboot.Model.Todo;
import com.we.springmvcboot.Service.TodoService;
import com.we.springmvcboot.Service.UserNotesRepository;
import antlr.collections.List;
import java.sql.Date;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
#Controller
public class TodoController {
#Autowired
private TodoService TodoRepo;
#RequestMapping(value = "/loginUser", method = RequestMethod.POST)
public #ResponseBody HashMap<String, Object> createPerson(#RequestParam("email") String email) {
System.out.println(todoservice.findByEmail(email));
HashMap<String, Object> map = new HashMap<>();
map.put("Status", 200);
map.put("Message", "Request Successful");
map.put("Data", todoservice.findBySql(1));
return map;
}
}
package com.we.springmvcboot.Service;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.we.springmvcboot.Model.OrderResponse;
import com.we.springmvcboot.Model.Todo;
#Repository
public interface TodoRepo extends JpaRepository<Todo, Integer> {
#Query(value="SELECT Notes.notesID, Notes.Title, Notes.Message, Notes.Date, UserNotes.UserID from
UserNotes JOIN Notes on UserNotes.NotesID=Notes.NotesID where userID=?1", nativeQuery=true)
List<Object> getSqlbyuserID(int user);
}
I am getting the output as
{
"Status": 200,
"Message": "Request Successful",
"Data": [
[
1,
"First Note",
"By Rohan",
"2017-03-03",
1
],
[
2,
"Second Note",
"By Rohan",
"2017-03-03",
1
]
]
}
but I want the output in the following format
{
“Status” : 200/400,
“Message” : “Request Successful”,
“Data” : {
“userNotes” : [
{
“notesID” : 1,
“title” : “abc”,
“message” : “content”,
“date” : 29/07/2020
"userID : 1
},
{
“notesID” : 2,
“title” : “abc”,
“message” : “content”,
“date” : 28/07/2020
"userID" : 2
}
]
}

If you are just beginner to the Spring Boot then I would suggest following coding structure. You will get the expected output easy way.
TodoController.java
package com.test.app.web;
import com.test.app.service.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
#Controller
public class TodoController {
#Autowired
private TodoService todoService;
#PostMapping("/loginUser")
public #ResponseBody HashMap<String, Object> createPerson(#RequestParam("email") String email) {
HashMap<String, Object> map = new HashMap<>();
map.put("Status", 200);
map.put("Message", "Request Successful");
map.put("Data", todoService.findByEmail(email));
return map; // Here, I return any generic data object. instead of creating map for all the apis.
}
}
TodoService.java
package com.test.app.service;
import com.test.app.domain.User;
import com.test.app.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class TodoService {
#Autowired
private UserRepository userRepository;
public List<User> findByEmail(String email) {
// Add your business logic here if you want to modify the fetched data.
return userRepository.findAllByEmail(email);
}
}
UserRepository.java
package com.test.app.repository;
import com.test.app.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Here Use, JPA naming convention to reduce the overhead of writing the native query.
List<User> findAllByEmail(String email);
}
User.java
package com.test.app.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name = "user")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "CREATION_TIMESTAMP", columnDefinition = "datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date creationTimestamp;
#Column(name = "LAST_UPDATED_TIMESTAMP", columnDefinition = "datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date lastUpdatedTimestamp;
#Column(name = "name")
private String name;
#Column(name = "middelName")
private String middelName;
#Column(name = "lastName")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "phoneNo")
private String phoneNo;
#Column(name = "contactPersonName")
private String contactPersonName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreationTimestamp() {
return creationTimestamp;
}
public void setCreationTimestamp(Date creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
public Date getLastUpdatedTimestamp() {
return lastUpdatedTimestamp;
}
public void setLastUpdatedTimestamp(Date lastUpdatedTimestamp) {
this.lastUpdatedTimestamp = lastUpdatedTimestamp;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMiddelName() {
return middelName;
}
public void setMiddelName(String middelName) {
this.middelName = middelName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
public String getContactPersonName() {
return contactPersonName;
}
public void setContactPersonName(String contactPersonName) {
this.contactPersonName = contactPersonName;
}
}
I hope, you will get the answer you are looking for.

You are sending a list of objects from List<Object> getSqlbyuserID(int user); and setting it to map.put("Data", todoservice.findBySql(1));.
You need to have another class userNotes to hold the values from getSqlbyuserID and set it in map.

Related

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Unsatisfied dependency expressed through field 'categoryRepository':

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'categoryService': Unsatisfied dependency expressed through field 'categoryRepository': Error creating bean with name 'categoryRepository' defined in com.example.demo.repository.CategoryRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Not a managed type: class com.example.demo.model.Category
package com.example.demo.model;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
#Table(name="categories")
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
private #NotNull String categoryName;
#Column(name = "description")
private String description;
#Column(name = "image")
private String imageUrl;
public Category() {
}
public Category(#NotNull String categoryName) {
this.categoryName = categoryName;
}
public Category(#NotNull String categoryName, String description) {
this.categoryName = categoryName;
this.description = description;
}
public Category(#NotNull String categoryName, String description, String imageUrl) {
this.categoryName = categoryName;
this.description = description;
this.imageUrl = imageUrl;
}
public String getCategoryName() {
return this.categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "User {category id=" + id + ", category name='" + categoryName + "', description='" + description + "'}";
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
package com.example.demo.controllers;
import java.util.ArrayList;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.service.CategoryService;
import com.example.demo.common.ApiResponse;
import com.example.demo.model.Category;
#RestController
#RequestMapping("category")
public class CategoryController {
#Autowired
private CategoryService categoryService;
#PostMapping("")
public ResponseEntity<ApiResponse> storeCategory(#Valid #RequestBody Category category) {
categoryService.saveCategory(category);
ArrayList<String> message = new ArrayList<String>();
message.add("Category is added successfully");
return new ResponseEntity<ApiResponse>(new ApiResponse(true, message), HttpStatus.OK);
}
}
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.demo.model.Category;
import com.example.demo.repository.CategoryRepository;
#Service
public class CategoryService {
#Autowired
private CategoryRepository categoryRepository;
public void saveCategory(Category category) {
// categoryRepository.saveAndFlush(category);
}
}
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Category;
#Repository("categoryRepository")
public interface CategoryRepository extends JpaRepository<Category, Integer> {
Category findByCategoryName(String categoryName);
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories
#ComponentScan(basePackages = { "com.example.demo.model.*" })
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
how to solve this error?
I ran the program but it showed this error.
Try adding this tag #EnableJpaRepositories in your MainApplication class and #ComponentScan(basePackages = {
"your entities package.*"
}

How to get selective columns in Export Csv in Spring boot

I am new to spring boot and i am creating a spring boot app to generate csv files from data fetched from database .I'm using h2 database for it and want to get selective columns from my entity-id,amount
entity class:
package com.reports.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity(name="reportDetails")
#Table(name = "reports")
public class Report {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
private long id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
#Column(name="amount")
private int amount;
public Report() {
super();
}
public Report(int id, String name, String email, int amount) {
super();
this.id = id;
this.name = name;
this.email = email;
this.amount = amount;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
main class:
package com.reports;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.reports.entities.Report;
import com.reports.repository.ReportsRepository;
#SpringBootApplication
public class ExportCsvApplication implements CommandLineRunner {
#Autowired
ReportsRepository reportsRepository;
public static void main(String[] args) {
SpringApplication.run(ExportCsvApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
List<Report> reports = new ArrayList<>();
// create dummy employees
reports.add(new Report(1,"roy","roy#123.com",2500));
reports.add(new Report(2,"joy","joy#123.com",2500));
reports.add(new Report(3,"soy","soy#123.com",2500));
reports.add(new Report(4,"moy","moy#123.com",2500));
reports.add(new Report(5,"noy","noy#123.com",2500));
reportsRepository.saveAll(reports);
}
}
repository :
package com.reports.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.reports.entities.IReport;
import com.reports.entities.Report;
#Repository("reportsRepository")
public interface ReportsRepository extends JpaRepository<Report,Long>{
}
Service class:
package com.reports.services;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.reports.entities.IReport;
import com.reports.entities.Report;
import com.reports.repository.ReportsRepository;
#Transactional
#Service
public class ReportsService {
#Autowired
ReportsRepository reportsRepository;
public List<Report> fetchAll() {
return (List<Report>) reportsRepository.findAll();
}
}
Controller:
package com.reports.controllers;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.opencsv.CSVWriter;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.reports.entities.Report;
import com.reports.services.ReportsService;
#RestController
public class ReportsController {
#Autowired
ReportsService reportsService;
#GetMapping("/export-report")
public void exportCSV(HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "details.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// create a csv writer
StatefulBeanToCsv<Report> writer = new StatefulBeanToCsvBuilder<Report>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false).build();
// write all employees to csv file
writer.write(reportsService.fetchAll());
}
}
I want to know what would be the best method to incorporate for it i tried query but faced errors.Please let me know how do i get this done
This is more of being related to the opencsv library than Spring or Spring Boot itself.
When constructing the StatefullBeanToCsvBuilder, you should use the withIgonreField builder property to instruct the final StatefullBeanToCsv on which fields to ignore for which types.
Say you want only the id and amount fields out of your Report entity, you can achieve this as follows:
#RestController
public class ReportsController {
#Autowired
ReportsService reportsService;
#GetMapping("/export-report")
public void exportCSV(HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "details.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// Configure the CSV writer builder
StatefulBeanToCsvBuilder<Report> builder = new StatefulBeanToCsvBuilder<Report>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false);
// Ignore any field except the `id` and `amount` ones
Arrays.stream(Report.class.getDeclaredFields())
.filter(field -> !("id".equals(field.getName()) || "amount".equals(field.getName())))
.forEach(field -> builder.withIgnoreField(Report.class, field));
// create a csv writer
StatefulBeanToCsv<Report> writer = builder.build();
// write all employees to csv file
writer.write(reportsService.fetchAll());
}
}

How to create list of list in Java Springboot?

I am new to java and springboot. I am trying to create one CRUD application using springboot.
I am using MySQL for storing the data.
Employee Model -
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "employees")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email_id")
private String emailId;
public Employee() {
}
public Employee(String firstName, String lastName, String emailId) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.emailId = emailId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
Employee Repository -
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.raksh.springboot.model.Employee;
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Employee Controller -
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.raksh.springboot.model.Employee;
import com.raksh.springboot.repository.EmployeeRepository;
#CrossOrigin(origins = "http://localhost:3000/")
#RestController
#RequestMapping("/api/v1/")
public class EmployeeController {
#Autowired
private EmployeeRepository employeeRepository;
// get all employees
#GetMapping("/employees")
public List<Employee> getAllEmployees(){
return employeeRepository.findAll();
}
}
The above controller is giving me the result in the JSON array of objects form as shown below
[
{
"id": 1,
"firstName": "Tony",
"lastName": "Stark",
"emailId": "tony#gmail.com"
},
{
"id": 2,
"firstName": "Thor",
"lastName": "Odinson",
"emailId": "thor#asgard.com"
}
]
But I need the response in the below form
{
total_items: 100,
has_more: true,
employees : {
1 : {
"id": 1,
"firstName": "Raksh",
"lastName": "Sindhe",
"emailId": "raksh#gmail.com"
},
2: {
"id": 2,
"firstName": "Thor",
"lastName": "Odinson",
"emailId": "thor#asgard.com"
}
}
}
Really appreciate the help.
You should create EmployeeResponse model (change the name as you see fit).
Add the additional fields you require.
The total_items could be calculated using list.size().
For the other field, I would add an additional query to the database for counting the number of rows, for example by id column.
compare if it's more than 100 and set the field to true.
You can see example here: Does Spring Data JPA have any way to count entites using method name resolving?
If in the "findAll" method you don't limit to 100 rows and you actually get all the employees and then move all except 100, you can set this field without the additional count query.
Simply you need to encapsulate the results in a DTO class and pass it back with the response.
total_items - can be inferred by the size of the list returned by the repository.
has_more - If you are using findAll() with repository call then you would get all the employees in the DB. Otherwise, you might have to introduce pagination with the repository.
employees - Include employees in a Map
ResponseDTO
public class ResponseDTO {
private int total_items;
private boolean has_more;
private Map<Integer, Employee> employees;
public ResponseDTO(int totalItems, boolean hasMore, Map<Integer, Employee> employees) {
this.total_items=totalItems;
this.has_more=hasMore;
this.employees=employees;
}
//constructors, getters, and setters
}
EmpoyeeController
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.raksh.springboot.model.Employee;
import com.raksh.springboot.repository.EmployeeRepository;
#CrossOrigin(origins = "http://localhost:3000/")
#RestController
#RequestMapping("/api/v1/")
public class EmployeeController {
#Autowired
private EmployeeRepository employeeRepository;
// get all employees
#GetMapping("/employees")
public List<Employee> getAllEmployees(){
Pageable employeePage = PageRequest.of(0, 100); //so you expect first 100 slice from all the employees in the DB.
Page<Employee> employees = employeeRepository.findAll(employeePage);
Map<Integer, Employee> employeeMap = getEmployeeMap(employees.getContent());
return new ResponseDTO(employees.getNumberOfElements(),employees.hasNext(),employeeMap );
}
private Map<Integer, Employee> getEmployeeMap(List<Employee> empoyees){
if(employees!=null && !empoyees.isEmpty){
Map<Integer, Employee> employeeMap = new HashMap<>();
for(Employee emp:empoyees){
employeeMap.put(emp.getId(),emp);
}
return employeeMap;
}
return null;
}
}

Spring-Data Project is not receiving my Get/Post "404 not found"

I finished creating a simple Spring-boot project in which I can enter users and through the Get command it returns me the name (from a list of identical names) with the oldest entry date. Unfortunately, every time I ask for Get it returns this ERROR:
D:\>curl -G localhost:8080/demo/first?=Biagio
{"timestamp":"2020-10-04T22:46:35.996+00:00","status":404,"error":"Not Found","message":"","path":"/demo/first"}
And to each of my POST / Add requests like this ERROR:
D:\>curl localhost:8080/demo/add -d name=Giovanni -d email=giovanni#gmail.com -d surname=Jackie
{"timestamp":"2020-10-04T22:40:51.928+00:00","status":404,"error":"Not Found","message":"","path":"/demo/add"}
Below I enter the interested parties of my project to try to get something out of it, because I have been stuck for days now
AccessingDataMysqlApplication.java
package com.example.accessingdatamysql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
public class AccessingDataMysqlApplication {
public static void main(String[] args) {
SpringApplication.run(AccessingDataMysqlApplication.class, args);
}
}
MainController.java
package com.example.accessingdatamysql.rest;
import javax.persistence.NoResultException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.service.UserService;
#RestController
#RequestMapping("/demo")
public class MainController {
#Autowired
private UserService userService;
#Transactional
//#RequestMapping(value = "/add/", method = RequestMethod.POST)
#PostMapping(path="/demo/add")
public String addNewUser(#PathVariable("name") String name, #PathVariable("email") String email,
#PathVariable("surname") String surname) {
UserDto n = new UserDto();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userService.create(n);
return "User Saved in DB";
}
#SuppressWarnings({ "rawtypes", "unchecked" })
//#RequestMapping(value = "/fetchUser/{name}", method = RequestMethod.GET)
#GetMapping("/demo/first")
public ResponseEntity<UserDto> fetchUser(#PathVariable("name") String name) {
System.out.println(name);
try {
UserDto namefound = userService.findFirstByName(name);
System.out.println("Name found");
ResponseEntity<UserDto> user = new ResponseEntity<UserDto>(namefound, HttpStatus.OK);
return user;
} catch(NoResultException ne) {
System.out.println("User not found");
return new ResponseEntity("User not found with name : " + name, HttpStatus.NOT_FOUND);
}
}
}
UserService.java
package com.example.accessingdatamysql.service;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
#Service
public interface UserService {
UserDto findFirstByName(String name);
void create(UserDto user);
}
UserServiceImpl.java
package com.example.accessingdatamysql.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository userRepository;
#Autowired
UserMapper mapper;
#Override
public UserDto findFirstByName(String name) {
UserEntity entity = userRepository.findFirstByName(name);
return mapper.toDtoMapper(entity);
}
#Override
public void create(UserDto user) {
UserEntity entity = mapper.toEntityMapper(user);
userRepository.create(entity);
}
}
UserMapper.java
package com.example.accessingdatamysql.util;
import org.mapstruct.Mapper;
import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
#Mapper(componentModel = "spring")
public interface UserMapper {
public UserEntity toEntityMapper (UserDto user);
public UserDto toDtoMapper (UserEntity userEntity);
}
UserRepository.java
package com.example.accessingdatamysql.repo;
import org.springframework.stereotype.Repository;
import com.example.accessingdatamysql.model.UserEntity;
#Repository
public interface UserRepository {
UserEntity findFirstByName(String name);
void create(UserEntity entity);
}
UserRepositoryImpl.java
package com.example.accessingdatamysql.service;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.springframework.stereotype.Component;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
#Component
public class UserRepositoryImpl implements UserRepository {
private final EntityManager em;
public UserRepositoryImpl(EntityManager entityManager) {
this.em = entityManager;
}
#Override
public UserEntity findFirstByName(String name) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<UserEntity> criteria = builder.createQuery(UserEntity.class);
Root<UserEntity> root = criteria.from(UserEntity.class);
criteria.select(root).where(builder.equal(root.get("name"), name));
criteria.orderBy(builder.asc(root.get("timestamp")));
TypedQuery<UserEntity> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
}
#Override
// per la creazione//
public void create(UserEntity entity) {
em.persist(entity);
}
}
UserDto.java
package com.example.accessingdatamysql.model;
import java.io.Serializable;
import java.sql.Timestamp;
public class UserDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7621330660870602403L;
/**
*
*/
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
private Timestamp timestamp;
private String email;
private String surname;
}
If you need I can also insert User.java and the pom, but the pom has no problems as the dependencies are all correct.
You have an additional demo in your path descriptions for GET and POST methods, you should remove it:
#GetMapping("/demo/first")
#PostMapping(path = "/demo/first")
It should be :
#GetMapping("/first")
#PostMapping(path = "/first")
This because you have already defined demo in the RequestMapping annotation in the class level.

GraphQL query Invalid syntax error while testing on Postman. Springboot server

The springboot application exposes the graphql API on the endpoint "localhost:8091/rest/books". When I test it with Postman passing the query in the body as graphQL type it gives error "Invalid Syntax", whereas when I pass the same query as raw text, it yields correct results. I'm using HSQL. The structure of my application is:
The files with their code respectively are:
Book.java
package com.techprimers.graphql.springbootgrapqlexample.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//#AllArgsConstructor
//#NoArgsConstructor
#Setter
#Getter
#Table
#Entity
public class Book {
#Id
private String isn;
public Book() {
super();
}
public Book(String isn, String title, String publisher, String[] authors, String publishedDate) {
super();
this.isn = isn;
this.title = title;
this.publisher = publisher;
this.authors = authors;
this.publishedDate = publishedDate;
}
public String getIsn() {
return isn;
}
public void setIsn(String isn) {
this.isn = isn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String[] getAuthors() {
return authors;
}
public void setAuthors(String[] authors) {
this.authors = authors;
}
public String getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
private String title;
private String publisher;
private String[] authors;
private String publishedDate;
}
BookRepository.java
package com.techprimers.graphql.springbootgrapqlexample.repository;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, String> {
}
BookResource.java
package com.techprimers.graphql.springbootgrapqlexample.resource;
import com.techprimers.graphql.springbootgrapqlexample.service.GraphQLService;
import graphql.ExecutionResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin(origins = "http://localhost:3000")
#RequestMapping("/rest/books")
#RestController
public class BookResource {
#Autowired
GraphQLService graphQLService;
#PostMapping
public ResponseEntity<Object> getAllBooks(#RequestBody String query) {
ExecutionResult execute = graphQLService.getGraphQL().execute(query);
return new ResponseEntity<>(execute, HttpStatus.OK);
}
}
AllBooksDataFetcher.java
package com.techprimers.graphql.springbootgrapqlexample.service.datafetcher;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import com.techprimers.graphql.springbootgrapqlexample.repository.BookRepository;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public class AllBooksDataFetcher implements DataFetcher<List<Book>>{
#Autowired
BookRepository bookRepository;
#Override
public List<Book> get(DataFetchingEnvironment dataFetchingEnvironment) {
return bookRepository.findAll();
}
}
BookDataFetcher.java
package com.techprimers.graphql.springbootgrapqlexample.service.datafetcher;
import com.techprimers.graphql.springbootgrapqlexample.model.Book;
import com.techprimers.graphql.springbootgrapqlexample.repository.BookRepository;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class BookDataFetcher implements DataFetcher<Book>{
#Autowired
BookRepository bookRepository;
#Override
public Book get(DataFetchingEnvironment dataFetchingEnvironment) {
String isn = dataFetchingEnvironment.getArgument("id");
return bookRepository.findById(isn).get();
}
}
And in the resources folder is
Books.graphql (contains schema)
schema {
query: Query
}
type Query {
allBooks: [Book]
book(id: String): Book
}
type Book {
isn: String
title: String
publisher: String
authors: [String]
publishedDate: String
}

Categories