Java Spring REST - No converter found...but I have getters? - java

I'm trying to practice REST API with Spring, but I am having an issue where it's saying
No converter found for return value of type: class org.codestrs.resources.Employee
From what I've read, this is mostly caused by there not being a getter methods for a class, Employee in this case. The weird thing is, I do have them in there.
EDIT: Just an FYI, this is a Dynamic Web Project, and I had to build my project without Spring Boot, so I manually added the spring functionality.
package org.codestrs.resources;
import java.util.Objects;
public class Employee {
private Long id;
private String name;
private String role;
Employee() {}
public Employee(Long id, String name, String role) {
this.id = id;
this.name = name;
this.role = role;
}
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getRole() {
return this.role;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setRole(String role) {
this.role = role;
}
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return Objects.equals(this.id,employee.id) && Objects.equals(this.name, employee.name) && Objects.equals(this.role, employee.role);
}
public String toString() {
return "Employee{" + "id=" + this.id + ", name=" + this.name + ", role=" + this.role + " }";
}
}
(And here's my controller for reference)
package org.codestrs.controller;
import org.codestrs.resources.Employee;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class EmployeeController {
#GetMapping("/employees/{id}")
Employee one(#PathVariable Long id) {
Employee emp = new Employee(id,"Nick","Designer");
return emp;
}
}
Looking at these, I'm not sure what the issue is. Any help would be greatly appreciated.

Related

why does #GetMapping not working as I expected?

I started learning Spring and been watching this video https://youtu.be/9SGDpanrc8U from
Amigoscode. I followed along and did what he did but my code acts differently than his, maybe i missed something, but I set on it for two hours trying to figure out what's not working and nothing works.
here is the code
package com.example.demo;
import java.time.LocalDate;
import java.time.Month;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.Student.*;
#SpringBootApplication
#RestController
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
#GetMapping
public List<Student> hello() {
return List.of(
new Student(
1L,
"Mariam",
"Marim.jamal#gmail.com",
LocalDate.of(2000, Month.JANUARY, 5),
21
)
);
}
}
And the Student class
package com.example.demo.Student;
import java.time.LocalDate;
public class Student {
private long id;
private String name;
private String email;
private LocalDate dob;
private Integer age;
public Student(Long id, String name, String email, LocalDate dob, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.dob = dob;
this.age = age;
}
public Student(String name, String email, LocalDate dob, Integer age) {
this.name = name;
this.email = email;
this.dob = dob;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long 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 LocalDate getDob() {
return dob;
}
public void setDob(LocalDate dob) {
this.dob = dob;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
#Override
public String toString() {
// TODO Auto-generated method stub
return "Student{" +
"id=" + id +
", name='" + name + "'" +
", email='" + email +"'" +
", dob=" + dob +
", age=" + age +
"}";
}
}
when he runs the code in the video, the websites loads a list with a single student details in it.
when I run it, it shows this:
Whitelabel Error Page \n This application has no explicit mapping for /error, so you are seeing this as a fallback
I checked Stack Overflow and other websites for this problem, most say it is because the controller doesn't handle what to do in case of an error, but that's not the case here. and the others say it's because packaging hierarchy, i tried splitting Demo2Application into two, one for the Application one for the RestController and put them in hierarchical order where Demo2Application shows before RestController, still didn't work so I reversed the splitting back to what the video showed.
Here is the log when I run:
Log
Truly Frustrated, will appreciate anything you have for me.
maybe you can assign a value to the annotation GetMapping,like #GetMapping("/query").then by this url http://localhost:8080/query to visit.

How to relate doctor and patient entities in spring boot jpa

I'm very new to spring boot. I am creating a health centre management system where I have 2 entities Doctor & Patient.
There are few rules that are followed
There can many doctors in a centre
There can be multiple patients too
A doctor can see multiple patients a day
But a patient can only have an appoinment with a single doctor at a time.
This is my Doctor entity:
package com.sb.projects.java.spring.medical_api.entities;
import com.sun.istack.NotNull;
import javax.persistence.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity
public class Doctors {
#Id
#NotNull
private int id;
private String name;
private String email;
private String degree;
private String specialization;
#OneToMany
private Set<Patients> patient = new HashSet<>();
public int 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 String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
public String getSpecialization() {
return specialization;
}
public void setSpecialization(String specialization) {
this.specialization = specialization;
}
public Set<Patients> getPatient() {
return patient;
}
public void setPatient(Set<Patients> patient) {
this.patient = patient;
}
}
This is my Patient entity:
package com.sb.projects.java.spring.medical_api.entities;
import com.sun.istack.NotNull;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
#Entity
public class Patients {
#Id
#NotNull
private int id;
private String name;
private String email;
private String contact_no;
#ManyToOne
private Doctors doctor;
public int 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 String getContact_no() {
return contact_no;
}
public void setContact_no(String contact_no) {
this.contact_no = contact_no;
}
public Doctors getDoctor() {
return doctor;
}
public void setDoctor(Doctors doctor) {
this.doctor = doctor;
}
}
Here are the few problems that I'm facing
I'm not sure about the type of relationship that I'm setting between the Doctor and Patient Enity is correct
If the relationship is correct then I'm not sure about the setPatient setter function in Doctor entity, that my implentation of the setter function is the right way of doing the thing or not
If the all the above points are okay then what will be a perfect mockup json object which will be in a http POST request body to test the Doctor Entity
Thanks for your help in advance.
I think you can create a Doctor without taking any patient into account something like this:
POST http://locahost:8080/v1/doctors
{
"name": "doctorName",
"email": "somemail#xyz.com",
"degree": "xyz",
"specialization": "a"
}
When you want to add a patient to your doctor then you would just call another endpoint to create a visit between your doctor and your patient
POST http://localhost:8080/visits/{patientId}
body...
{
"doctorId": idOfDoctor,
}
With this you would attack the patient's db repository to create a relation between your patient and your doctor.
It sounds extrange to me to relate directly the doctor with the patients, i would do a middle relation like "VISITS" with the day of visit and the hour...

Java defining generic class as parameter for static method, to pass entity objects

Dear Stackoverflow community,
I am new to working with generics and have problems with using genericts correctly. What I want to do is, that a static method can take a generic Object as a parameter. My idea is, to pass Entity Objects as parameter and after return a UserDetailsImpl object. So I want to make this method able to handle different entity classes and dont write boilerplatecode. For this I write an easy Box class for it.
Box.java
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
Now I try to use it to pass generic object as parameter in my UserDetailsImpl.java class in the static build method:
package com.yildiz.tradilianz.security.services;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String email;
#JsonIgnore
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserDetailsImpl(Long id, String username, String email, String password,
Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static UserDetailsImpl build(Box<Object> user) {
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getName().name()))
.collect(Collectors.toList());
return new UserDetailsImpl(
user.getId(),
user.getUsername(),
user.getEmail(),
user.getPassword(),
authorities);
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
#Override
public String getPassword() {
return password;
}
#Override
public String getUsername() {
return username;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
#Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
UserDetailsImpl user = (UserDetailsImpl) o;
return Objects.equals(id, user.id);
}
}
Now the problem is, that the passed Object doesn't know the whole get() methods I try to access like user.getId(), user.getRoles(), user.getPassword() etc. I want that the generic Box Class contains any Object but how to declare this method I need to access from it?
Otherwise it ends up with "The method getRoles() is undefined for the type Box"
What I wanted to pass as generic Object is my customer entity class, but if it returns null instead i want to test if retailer entity class works and so on in **UserDetailsServiceImpl **:
package com.yildiz.tradilianz.security.services;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yildiz.tradilianz.auth.User;
import com.yildiz.tradilianz.auth.UserRepository;
import com.yildiz.tradilianz.customer.Customer;
import com.yildiz.tradilianz.customer.CustomerDTO;
import com.yildiz.tradilianz.customer.CustomerRepository;
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
CustomerRepository customerRepository;
#Autowired
CustomerDTO customerDTO;
#Override
#Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Check for username or email passed through username parameter
boolean valid = EmailValidator.getInstance().isValid(username);
if (valid == false) {
/*
* Build with UserDetailsImpl but if user for Customer class is null I want to try another repository and do
* something like this:
* Retailer user = retailerRepository.findByUsername(username); And if it is not null
* it should pass user Object which class is Retailer and so on.
*
*/
Customer user = customerRepository.findByUsername(username);
return UserDetailsImpl.build(user);
} else {
Customer user = customerRepository.findByEmail(username):
return UserDetailsImpl.build(user);
}
}
}
customer entity class
package com.yildiz.tradilianz.customer;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.hibernate.annotations.CreationTimestamp;
import com.yildiz.tradilianz.auth.ERole;
#Entity
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank
#Size(max = 20)
private String username;
#NotBlank
#Size(max = 120)
private String password;
#Column(nullable = false)
private String givenName;
#Column(nullable = false)
private String surname;
private String birthday;
private String streetAddress;
private String city;
private String postalCode;
#Column(updatable = false, nullable = false)
private String email;
private String phoneNumber;
#CreationTimestamp
private Timestamp timestamp;
private Double balance;
private Integer bonuspoints;
private String role;
protected Customer() {
}
public Customer(String username,String password, String givenName, String surname, String birthday, String streetAddress, String city,
String postalCode, String email, String phoneNumber, Double balance, Integer bonuspoints, String role) {
this.username = username;
this.password = password;
this.givenName = givenName;
this.surname = surname;
this.birthday = birthday;
this.streetAddress = streetAddress;
this.city = city;
this.postalCode = postalCode;
this.email = email;
this.phoneNumber = phoneNumber;
this.balance = balance;
this.bonuspoints = bonuspoints;
this.role = role;
}
#Override
public String toString() {
return ("Benutzername: "+username+ "Passwort: "+password+ "Vorname: " + givenName + " Nachname: " + surname +
" Geburtstag: " + birthday + " Straße: "+ streetAddress + " Stadt: " + city + " Postleitzahl: " +
postalCode + " E-Mail-Adresse: " + email+ " Telefonnummer: " + phoneNumber + "Kontostand: " + balance +
" Bonuspunkte: " + bonuspoints+" Rolle:"+role);
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public Long getId() {
return id;
}
public String getGivenName() {
return givenName;
}
public String getSurname() {
return surname;
}
public String getBirthday() {
return birthday;
}
public String getStreetAddress() {
return streetAddress;
}
public String getCity() {
return city;
}
public String getPostalCode() {
return postalCode;
}
public String getEmail() {
return email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Timestamp getTimestamp() {
return timestamp;
}
public Integer getBonuspoints() {
return bonuspoints;
}
public Double getBalance() {
return balance;
}
public String getRole() {
return role;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public void setCity(String city) {
this.city = city;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public void setEmail(String email) {
this.email = email;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public void setBonuspoints(Integer bonuspoints) {
this.bonuspoints = bonuspoints;
}
public void setRole(String role) {
this.role = role;
}
}
**
Can you pls give me tipps how I do it the right way?
in your build() method, you are passing Box, so it only knows the type as Object.
public static UserDetailsImpl build(Box<Object> user)
when you try to access it, you are trying to access the methods from type Customer, which it will not have any clue what methods are associated with Customer object. (user reference will only know about Box class methods)
so, what you need to do is change Box<Object> to Box<Customer> and then access the Customer's methods using
user.get().getId() etc.
here user.get() will return the underlying type object and you will have access to its methods.
or what you can also do is if you want the generic type to be a specific instance type, you can change your Box class implementation to be (extends T type to an instance of that class), for e.g. Customer in your case. (you ca create an interface or abstract class that will have methods that you are trying to use)
public class Box< T extends Customer>
public class Box<T extends CustomerInterface> etc.

Update() method doesn't work in Play Framework with h2 database

I am trying to update a list of a company class I created in Play Framework.
It all works until i get to the company.update(), which doesn't save to the database as it should.
Here is my Company class:
package models;
import io.ebean.Finder;
import io.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Company extends Model {
#Id
public Integer id;
public String code;
public String name;
public String adress;
public String fiscalCode;
public String bankAccount;
public static Finder<Integer, Company> find = new Finder<>(Company.class);
public String getFiscalCode() {
return fiscalCode;
}
public void setFiscalCode(String fiscalCode) {
this.fiscalCode = fiscalCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
}
And here are my update and edit methods:
public Result editCompany(Integer id){
Company company = Company.find.byId(id);
if(company == null)
{
return notFound("Company not found");
}
Form<Company> companyForm = formFactory.form(Company.class).fill(company);
return ok(editCompany.render(companyForm));
}
public Result updateCompany(){
Form<Company> companyForm = formFactory.form(Company.class).bindFromRequest();
if(companyForm.hasErrors())
{
flash("danger","Please Correct the Form Below");
return badRequest(editCompany.render(companyForm));
}
Company newcompany = companyForm.get();
Company company = Company.find.byId(newcompany.id);
if (company == null) {
flash("danger", "Book not found");
redirect(routes.CompanyController.indexCompanies());
}
company.code = newcompany.code;
company.name = newcompany.name;
company.adress = newcompany.adress;
company.fiscalCode = newcompany.fiscalCode;
company.bankAccount = newcompany.bankAccount;
company.update();
flash("success","Company Details Updated Successfully");
return redirect(routes.CompanyController.indexCompanies());
}
The new company entity has updated values, but they don't save in the database. I checked by printing to the console company.name.
I hope you can help me. Thank you!
I seem to have figured it out.
The problem goes away after using getters and setters and doing a recompile. Therefore,
company.code = newcompany.code;
company.name = newcompany.name;
company.adress = newcompany.adress;
company.fiscalCode = newcompany.fiscalCode;
company.bankAccount = newcompany.bankAccount;
becomes
company.setCode(newcompany.getCode());
company.setName(newcompany.getName());
company.setAdress(newcompany.getAdress());
company.setFiscalCode(newcompany.getFiscalCode());
company.setBankAccount(newcompany.getBankAccount());

Error in returning list of objects for the spring boot application in microservices development

I followed the microservices tutorial from youtube to create independent services (spring boot Application)
I created a service implementation java file providing method definitions for the request mapping URL (/catalog/userId) for the read operation
To the above requested URL, returning a list of objects as the response body (HTTP response) for the HTTP read request
In the java, error occurring for the function definition of sending a list of objects
The error occurs in line 17 of MovieCatalogResource.java stating the illegal start of expression, unexpected token
I researched for the error but still I am struck with the execution
can you guys kindly provide your help to resolve issue with your suggestions
Providing the code below
CatalogItem.java
package com.example.moviecatalogservice;
public class CatalogItem {
private String name;
private String desc;
private int rating;
public CatalogItem(String name, String desc, int rating){
this.name = name;
this.desc = desc;
this.rating = rating;
}
public int getRating(){
return rating;
}
public void setRating(){
this.rating = rating;
}
public String getName(){
return name;
}
public void setName(){
this.name = name;
}
public String getDesc(){
return desc;
}
public void setDesc(){
this.desc = desc;
}
}
MovieCatalogService.java
package com.example.moviecatalogservice;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.an notation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
#RestController
#RequestMapping("/catalog")
public class MovieCatalogResource {
#RequestMapping("/{userId}")
//public List<CatalogItem> getCatalog(#PathVariable("userId") String userId){
public List<CatalogItem> getCatalog(#PathVariable("userId") String userId){
return Collections.singletonList(
new CatalogItem(name: "transformers", desc:"Test", rating:4)
);
}
}
change
new CatalogItem(name: "transformers", desc:"Test", rating:4)
To
new CatalogItem("transformers", "Test", 4)
You must have a matching CatalogItem() constructor in CatalogItem
Entity Or Model
After a change at line no 17 of MovieCatalogResource.java it will look like as below
#RestController
#RequestMapping("/catalog")
public class MovieCatalogResource {
#RequestMapping("/{userId}")
//public List<CatalogItem> getCatalog(#PathVariable("userId") String userId){
public List<CatalogItem> getCatalog(#PathVariable("userId") String userId){
return Collections.singletonList(
new CatalogItem("transformers", "Test", 4)
);
}
}
Working Example
Controller.java
#GetMapping("/{id}")
public List<User> getUser(#PathVariable(name="id") int id)
{
return Collections.singletonList(
new User(1,"username")
);
}
User.java
public class User {
private int id;
private String name;
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}
Tested using Postman
Why are you doing this :
new CatalogItem(name: "transformers", desc:"Test", rating:4)
instead of this :
new CatalogItem("transformers", "Test", 4)
at line no 17 of MovieCatalogResource.java?
Change the below statement from new CatalogItem(name: "transformers", desc:"Test", rating:4) to new CatalogItem("transformers","Test",4)

Categories