How I can call method using web client? - spring

I wanna show new scene (JavaFX) when my post-request will be successfully completed, and show alerts when it will be 5xx/4xx errors.
When i try to do this using WebFlux library, I getting error like "Bad return type in lambda expression: Optional cannot be converted to Mono<? extends Throwable>"
AuthController.java
buttonAuth.setOnAction(
actionEvent -> {
UserAuth userAuth = UserAuth
.builder()
.login(loginAuth.getText())
.password(passAuth.getText())
.build();
webClient.post()
.uri("http://localhost:10120/message/authorization")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(userAuth)
.retrieve()
.onStatus(
HttpStatus::is5xxServerError,
response -> alertService.showAlert(Alert.AlertType.ERROR, "Error",
"Server error", false))
.onStatus(
HttpStatus::is4xxClientError,
response -> alertService.showAlert(Alert.AlertType.ERROR, "Error",
"Client error", false))
.onStatus(
HttpStatus.OK,
response -> Platform.runLater(()-> {setScene(buttonAuth,"Main Menu", MainMenuController.class, fxWeaver);}))
.bodyToMono(Void.class)
.block();
}
});
UserAuth.java
import lombok.*;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Getter
#Setter
#ToString
#Builder(toBuilder = true)
public class UserAuth {
public String login;
public String password;
}
AlertService.java
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Optional;
#Service
#RequiredArgsConstructor
public class AlertService {
public Optional<ButtonType> showAlert(Alert.AlertType type, String title, String content, boolean NeedToReturnResult) {
Alert alert = new Alert(type);
alert.setTitle(title);
alert.setContentText(content);
alert.setHeaderText(null);
Optional<ButtonType> result = alert.showAndWait();
if (NeedToReturnResult) return result;
else {
return null;
}
}
}
BaseController.java --- need to set scene when request successfully completed
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import net.rgielen.fxweaver.core.FxWeaver;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class BaseController {
#Autowired
private Stage stage;
public void setScene(Button button, String title, Class controller, FxWeaver fxWeaver) {
button.getScene().getWindow().hide();
Parent root = (Parent) fxWeaver.loadView(controller);
stage.setScene(new Scene(root));
stage.setTitle(title);
stage.setResizable(false);
stage.show();
}
public void setScene(Hyperlink link, String title, Class controller, FxWeaver fxWeaver) {
link.getScene().getWindow().hide();
Parent root = (Parent) fxWeaver.loadView(controller);
stage.setTitle(title);
stage.setResizable(false);
stage.setScene(new Scene(root));
stage.show();
}
public void clearFields(TextField firstNameReg, TextField secondNameReg, TextField loginReg, PasswordField passReg, TextField mailReg) {
firstNameReg.clear();
secondNameReg.clear();
loginReg.clear();
passReg.clear();
mailReg.clear();
}
public void clearFields(TextField login, PasswordField password) {
login.clear();
password.clear();
}
}
Server-part -- here I tried to send some statuses when get request, but i don't know how to do that right
#RequestMapping(
value = "/authorization",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<String> authorizationUser(#Valid UserDTO userDTO) {
log.info("[UserController.authorizationUser] personDTO = {}", userDTO);
log.info("[UserController.authorizationUser] personDTO = {}", userService.authorizationUser(userDTO).authorization);
if(userService.authorizationUser(userDTO).authorization){
return Flux.just("ok");
}else{
return Flux.just("bad_request");
}
}

Related

Custom Exception not thrown in controller-method when no data is found in database

My controller always give Internal server error whenever my condition fail, and are suppose to throw custom exception ResourceNotFoundException.
When I call account/1-endpoint (no account with id 1 in database) I expect an ResourceNotFoundException, but instead I get Internal server Error.. I do not understand why ResourceNotFoundException is not thrown, I watched several youtube tutorials on the topic.
Please help by providing possible solutions.
My model classes are
package com.bank2.Model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Proxy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#javax.persistence.Table(name="Account")
#Proxy(lazy = false)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Account {
#Id
int accountNumber;
#Column(name="balance")
Double balance;
#Column(name="accountType")
String accountType;
public Account() {
super();
}
#Override
public String toString() {
return "Account [accountNumber=" + accountNumber + ", balance=" + balance + ", accountType=" + accountType + "]";
}
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
public Account(int accountNumber, Double balance, String accountType) {
super();
this.accountNumber = accountNumber;
this.balance = balance;
this.accountType = accountType;
}
}
package com.bank2.Model;
import java.util.List;
import javax.persistence.CascadeType;
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.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Proxy;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name="Customer")
#Proxy(lazy = false)
#JsonIgnoreProperties(ignoreUnknown = true)
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Integer customerId;
#Column(name="customerName")
String customerName;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL,targetEntity = Account.class)
#JoinColumn(name = "ca_fk",referencedColumnName ="customerId")
private List<Account> accounts;
public Customer() {
super();
}
public Customer(Integer customerId, String customerName, List<Account> accounts) {
super();
this.customerId = customerId;
this.customerName = customerName;
this.accounts = accounts;
}
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public List<Account> getAccount() {
return accounts;
}
public void setAccount(List<Account> accounts) {
this.accounts = accounts;
}
#Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName=" + customerName + ", accounts=" + accounts + "]";
}
}
My service classes are
package com.bank2.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bank2.Model.Customer;
import com.bank2.repository.CustomerRepository;
#Service
public class CustomerService {
#Autowired
CustomerRepository customerRepository;
public Customer customerCreate(Customer customer) {
Customer x= customerRepository.save(customer);
return x;
}
}
package com.bank2.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bank2.Model.Account;
import com.bank2.repository.AccountRepository;
#Service
public class AccountService {
#Autowired
AccountRepository accountRepository;
public Account findAccountById(int accountNumber) {
return accountRepository.getById(accountNumber);
}
}
my controller class are
package com.bank2.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.bank2.Exception.ResourceNotFoundException;
import com.bank2.Model.Account;
import com.bank2.ServiceImpl.AccountService;
#RestController
#RequestMapping("/account")
public class AccountController {
#Autowired
AccountService accountService;
#GetMapping("/{accountNumber}")
public ResponseEntity<?> getAccountById(#PathVariable("accountNumber") int accountNumber){
Account acc=accountService.findAccountById(accountNumber);
if(acc==null) {
throw new ResourceNotFoundException("Account [accountNumber="+accountNumber+"] can't be found");
}else {
return new ResponseEntity<>(acc,HttpStatus.FOUND);
}
}
package com.bank2.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
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.bank2.Exception.ResourceNotFoundException;
import com.bank2.Model.Customer;
import com.bank2.ServiceImpl.CustomerService;
#RestController
#RequestMapping("/customer")
public class CustomerController {
#Autowired
CustomerService customerService;
#PostMapping("/createCust")
public ResponseEntity<?> CreateCustomer(#RequestBody Customer customer){
Customer cus=customerService.customerCreate(customer);
Optional<Customer> cus1 = Optional.ofNullable(cus);
if(cus1.isEmpty()) {
throw new ResourceNotFoundException("customer not created!!");
}else {
return new ResponseEntity<>(cus,HttpStatus.CREATED);
}
}
}
my expection classes are
package com.bank2.Exception;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.http.HttpStatus;
public class ApiErrors {
String message;
List<String> details;
HttpStatus status;
LocalDateTime timestamp;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<String> getDetails() {
return details;
}
public void setDetails(List<String> details) {
this.details = details;
}
public HttpStatus getStatus() {
return status;
}
public void setStatus(HttpStatus status) {
this.status = status;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public ApiErrors() {
super();
// TODO Auto-generated constructor stub
}
public ApiErrors(String message, List<String> details, HttpStatus status, LocalDateTime timestamp) {
super();
this.message = message;
this.details = details;
this.status = status;
this.timestamp = timestamp;
}
#Override
public String toString() {
return "ApiErrors [message=" + message + ", details=" + details + ", status=" + status + ", timestamp="
+ timestamp + "]";
}
}
package com.bank2.Exception;
public class ResourceNotFoundException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
public ResourceNotFoundException() {
super();
}
public ResourceNotFoundException(String message) {
super(message);
}
}
package com.bank2.Exception;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
#ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
#ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex){
String msg=ex.getMessage();
List<String> details=new ArrayList<>();
details.add("Resource not found");
ApiErrors errors=new ApiErrors(msg,details,HttpStatus.BAD_REQUEST,LocalDateTime.now());
return new ResponseEntity<Object>(errors,HttpStatus.BAD_REQUEST);
}
#ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleOther(Exception ex){
String msg=ex.getMessage();
List<String> details=new ArrayList<>();
details.add("Other Exceptions");
ApiErrors errors=new ApiErrors(msg,details,HttpStatus.INTERNAL_SERVER_ERROR,LocalDateTime.now());
return new ResponseEntity<Object>(errors,HttpStatus.INTERNAL_SERVER_ERROR);
}
}
This is the Internal server error I have gotten so far in Postman:
{
"message": "Unable to find com.bank2.Model.Account with id 1; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.bank2.Model.Account with id 1",
"details": [
"Other Exceptions"
],
"status": "INTERNAL_SERVER_ERROR",
"timestamp": "2022-04-02T22:09:28.0486246"
}
My repositories are
'''
package com.bank2.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.bank2.Model.Account;
#Repository
public interface AccountRepository extends JpaRepository<Account, Integer> {
}
'''
'''
package com.bank2.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.bank2.Model.Customer;
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
}
'''
From the Documentation JpaRepository.html#getById-ID-
T getById(ID id)
Returns a reference to the entity with the
given identifier. Depending on how the JPA persistence provider is
implemented this is very likely to always return an instance and throw
an EntityNotFoundException on first access. Some of them will reject
invalid identifiers immediately.
The error message you get shows ...nested exception is EntityNotFoundException, so that could be normal...
So you could throw a ResourceNotFoundException in your service when the Account is not found.
#Service
public class AccountService {
public Account findAccountById(int accountNumber) {
try {
return accountRepository.getById(accountNumber);
} catch(EntityNotFoundException e) {
throw new ResourceNotFoundException("Account [accountNumber="+accountNumber+"] can't be found")
}
}

Map/access array inside object on Pojo

How can I access and map an array inside an object on Pojo Spring Boot?
This is what I wanted to map
{
"customers": [
{
"customerId": "0434556574",
"paymentCode": "90501"
}
]
}
You would need to classes to match the JSON structure:
public class CustomersData {
private List<Customer> customers;
// Constructor, getter and setter
}
public class Customer {
private String customerId;
private String paymentCode;
// Constructor, getter and setter
}
Important thing is to make sure your JSON properties name matches the attributes name in your Java classes (thus avoiding explicit mapping between them).
Hi There are lot's of utility libraries you can convert JSON to required java class so that you can instantiate in right way.
Example based on your input:
-----------------------------------com.example.Customer.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"customerId",
"paymentCode"
})
#Generated("jsonschema2pojo")
public class Customer {
#JsonProperty("customerId")
private String customerId;
#JsonProperty("paymentCode")
private String paymentCode;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("customerId")
public String getCustomerId() {
return customerId;
}
#JsonProperty("customerId")
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
#JsonProperty("paymentCode")
public String getPaymentCode() {
return paymentCode;
}
#JsonProperty("paymentCode")
public void setPaymentCode(String paymentCode) {
this.paymentCode = paymentCode;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"customers"
})
#Generated("jsonschema2pojo")
public class Example {
#JsonProperty("customers")
private List<Customer> customers = null;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty("customers")
public List<Customer> getCustomers() {
return customers;
}
#JsonProperty("customers")
public void setCustomers(List<Customer> customers) {
this.customers = customers;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Reference :jsontopojo

No qualifying bean of type 'com.springmvc.dao.UserDAO' available: expected at least 1 bean which qualifies as autowire candidate

I am getting an error as No qualifying bean of type 'com.springmvc.dao.UserDAO' available: expected at least 1 bean which qualifies as autowire candidate. for the following code, My base class is "com.springmvc"
My Controller Class is
package com.springmvc.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.springmvc.dao.UserDAO;
import com.springmvc.dao.UserDAOImpl;
import com.springmvc.type.User;
#Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
#Autowired
private UserDAO usrdao;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("Date", formattedDate );
return "index";
}
/*
#RequestMapping(value="/login",method = RequestMethod.POST)
public String welcome(Locale locale,Model model,#ModelAttribute("LoginBean")LoginBean login){
if(login != null && login.getUserName() != "" && login.getPassword() != ""){
if(login.getUserName().equals("ajith") && login.getPassword().equals("123")){
model.addAttribute("msg","Welcome "+login.getUserName());
return "welcome";
}
else{
model.addAttribute("error","Invalid Login Details");
return "index";
}
}
else{
model.addAttribute("error","Please Enter Login Details");
return "index";
}
}
*/
#RequestMapping(value="/checkLogin",method = RequestMethod.POST)
public String CheckUser(Model model,#ModelAttribute("User")User user){
if(user != null && user.getUserName() != "" && user.getPass() != ""){
boolean isActive = usrdao.isActiveUser(user.getUserName(), user.getPass());
if(isActive){
List<User> usrLst = usrdao.ListAllUsers();
model.addAttribute("message",user.getUserName());
model.addAttribute("usrLst",usrLst);
return "home";
}
else{
model.addAttribute("error","Invalid Login Details");
return "index";
}
}
return "index";
}
#RequestMapping(value="/createUser", method = RequestMethod.GET)
public String RedirectCreateUser(Model model){
return "createUser";
}
public String createUser(Model model, #ModelAttribute User user){
usrdao.CreateOrUpdateUser(user);
return "";
}
}
UserDAO
package com.springmvc.dao;
import java.util.List;
import com.springmvc.type.User;
public interface UserDAO {
public void CreateOrUpdateUser(User user);
public void DeleteUser(int uid);
public User GetUser(int uid);
public List<User> ListAllUsers();
public boolean isActiveUser(String userName,String pass);
}
UserDAOImpl
package com.springmvc.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Repository;
import com.springmvc.type.User;
#Repository("UserDAO")
public class UserDAOImpl implements UserDAO {
private JdbcTemplate jdbc;
/*
public void setJdbc(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
*/
public UserDAOImpl(DataSource DS) {
jdbc = new JdbcTemplate(DS);
}
#Override
public void CreateOrUpdateUser(User user) {
if(user.getUid() == 0){
String query = "INSERT INTO userdetails(UserName,Name,Pass) VALUES(?,?,?)";
jdbc.update(query,user.getUserName(),user.getName(),user.getPass());
}
else{
String query = "UPDATE userdetails SET UserName = ?,Name = ?,Pass = ?,isActive = ? WHERE id = ?";
jdbc.update(query, user.getUserName(),user.getName(),user.getPass(),user.getIsActive(),user.getUid());
}
}
#Override
public void DeleteUser(int uid) {
String query = "DELETE FROM userdetails WHERE id = ?";
jdbc.update(query, uid);
}
#Override
public User GetUser(int uid) {
String query = "SELECT * FROM userdetails WHERE id = ?";
return jdbc.query(query, new ResultSetExtractor<User>() {
#Override
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
if(rs.next()){
User user = new User();
user.setUid(rs.getInt("id"));
user.setUserName(rs.getString("UserName"));
user.setName(rs.getString("Name"));
user.setIsActive(rs.getInt("isActive"));
return user;
}
return null;
}
});
}
#Override
public List<User> ListAllUsers() {
String query = "SELECT * FROM userdetails";
List <User> usrLst = jdbc.query(query, new RowMapper<User>() {
#Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setUid(rs.getInt("id"));
user.setUserName(rs.getString("UserName"));
user.setName(rs.getString("Name"));
user.setIsActive(rs.getInt("isActive"));
return user;
}
});
return usrLst;
}
#Override
public boolean isActiveUser(String userName, String pass) {
String query = "SELECT id FROM userdetails WHERE UserName = ? AND Pass = ? AND isActive = 1";
SqlRowSet rs = jdbc.queryForRowSet(query,userName,pass);
if(rs.next())
return true;
else
return false;
}
}
Thank You
UserDAOImpl do not have default constructor. either add default constructor or autowire the construction arg.
Spring is using a strong naming convention.
Try to use as a variable userDao as the autowired variable and use the same string in the #repository.
See this little explanation here:
https://www.tutorialspoint.com/spring/spring_beans_autowiring.htm

Spring - Failed to convert property value of type java.lang.String to required type

I am making a project of the Housing Association in Spring.
When I'm trying to add an object to my list of apartments I'm getting an error that is written somehow on the page:
https://s28.postimg.org/vrhy6mbd9/blad.jpg
Apartments have relation Many to One Building.
Apartment Controller:
package pl.dmcs.spoldzielnia.controllers;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import pl.dmcs.spoldzielnia.domain.Apartment;
import pl.dmcs.spoldzielnia.service.ApartmentService;
import pl.dmcs.spoldzielnia.service.BuildingService;
#Controller
#SessionAttributes
public class ApartmentController {
#Autowired
ApartmentService apartmentService;
#Autowired
BuildingService buildingService;
#RequestMapping("admin/apartment")
public String listApartment(Map<String, Object> map, HttpServletRequest request) {
int apartmentId = ServletRequestUtils.getIntParameter(request, "apartmentId" , -1);
if (apartmentId > 0)
{
Apartment apartment = apartmentService.getApartment(apartmentId);
apartment.setBuilding(buildingService.getBuilding(apartmentService.getApartment(apartmentId).getBuilding().getId()));
map.put("selectedBuilding", apartmentService.getApartment(apartmentId).getBuilding().getId());
map.put("apartment", apartment);
}
else
map.put("apartment", new Apartment());
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
#RequestMapping(value = "admin/addApartment", method = RequestMethod.POST)
public String addContact(#ModelAttribute("apartment") Apartment apartment, BindingResult result,
HttpServletRequest request, Map<String, Object> map) {
if (result.getErrorCount()==0)
{
if (apartment.getId()==0)
{
if (apartment.getBuilding().getId() > 0)
apartment.setBuilding(buildingService.getBuilding(apartment.getBuilding().getId()));
apartmentService.addApartment(apartment);
}
else
{
apartmentService.editApartment(apartment);
}
return "redirect:/admin/apartment.html";
}
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
#RequestMapping("admin/delete/apartment/{apartmentId}")
public String deleteApartment(#PathVariable("apartmentId") Integer apartmentId) {
apartmentService.removeApartment(apartmentId);
return "redirect:/admin/apartment.html";
}
// #RequestMapping("/apartment")
// public ModelAndView showContacts() {
//
// return new ModelAndView("apartment", "command", new Apartment());
// }
Domain:
package pl.dmcs.spoldzielnia.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="apartment")
public class Apartment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
int id;
#Column(name="apartmentNumber", nullable=false)
private String number;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#ManyToOne
private Building building;
public Building getBuilding() {
return building;
}
public void setBuilding(Building building) {
this.building = building;
}
}
}
Building Service Implementation:
package pl.dmcs.spoldzielnia.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pl.dmcs.spoldzielnia.dao.BuildingDAO;
import pl.dmcs.spoldzielnia.domain.Building;
import pl.dmcs.spoldzielnia.domain.Building;
#Service
#Transactional
public class BuildingServiceImpl implements BuildingService{
#Autowired
BuildingDAO buildingDAO;
#Transactional
public void addBuilding(Building building) {
buildingDAO.addBuilding(building);
}
#Transactional
public List<Building> listBuilding() {
return buildingDAO.listBuilding();
}
#Transactional
public Building getBuilding(int id) {
return buildingDAO.getBuilding(id);
}
#Transactional
public void removeBuilding(int id) {
buildingDAO.removeBuilding(id);
}
#Transactional
public void editBuilding(Building building) {
buildingDAO.editBuilding(building);
}
}
Could you help me to solve my problem?
The problem is that you are assuming that Spring MVC is going to be able to fill your Apartment object from the data passed. From the form it looks like the Building number is 12, which probably is a unique identifier for the Building in the database, but how is Spring MVC going to know how to go to the database, retrieve the proper building object and put it into the Apartment object?
Remember that objects mapped through SpringMVC parameters are regular Java POJOs, not Hibernate attached entities. So, when the mapping occurs SpringMVC is trying to put "12" into the building attribute of type Building into your POJO (which explains the error you are getting).
You have two options:
First, you can register a custom formatter, that will use the passed id to retrieve a Building from the database:
import org.springframework.core.convert.converter.Converter;
public class BuildingIdToBuildingConverter implements Converter<String, Building> {
private BuildingService buildingService;
public BuildingIdToBuildingConverter(BuildingService buildingService) {
this.buildingService = buildingService;
}
#Override
public Building convert (String id) {
return buildingService.getBuilding(id);
}
}
And register it:
public class AppConfig extends WebMvcConfigurerAdapter {
...
#Bean
public BuildingService buildingService(){
return new BuildingService();
}
#Override
public void addFormatters (FormatterRegistry registry) {
registry.addConverter(new BuildingIdToBuildingConverter(buildingService()));
}
}
Second, do this work manually by sending the building id in a separate parameter:
#RequestMapping(value = "admin/addApartment", method = RequestMethod.POST)
public String addContact(#ModelAttribute("apartment") Apartment apartment, #RequestParam("buildingId") String buildingId, BindingResult result, HttpServletRequest request, Map<String, Object> map) {
if (result.getErrorCount()==0){
if (apartment.getId()==0){
apartment.setBuilding(buildingService.getBuilding(buildingId));
apartmentService.addApartment(apartment);
}
}
else{
apartmentService.editApartment(apartment);
}
return "redirect:/admin/apartment.html";
}
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
And change your HTML accordingly to send the buildingId value.

Spring MVC to REST

I have a Spring MVC aplication. I want to convert it to a RESTful
webservice, which returns a JSON response. Can somebody help me with this??
Basically, I want to convert my controller to a REST controller.
My Code :
///////////////////////////PersonController//////////////////////////////
package com.journaldev.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.service.PersonService;
#Controller
public class PersonController {
private PersonService personService;
#Autowired(required=true)
#Qualifier(value="personService")
public void setPersonService(PersonService ps){
this.personService = ps;
}
#RequestMapping(value = "/persons", method = RequestMethod.GET)
public String listPersons(Model model) {
model.addAttribute("person", new Person());
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
//For add and update person both
#RequestMapping(value= "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person p){
if(p.getId() == 0){
//new person, add it
this.personService.addPerson(p);
}else{
//existing person, call update
this.personService.updatePerson(p);
}
return "redirect:/persons";
}
#RequestMapping("/remove/{id}")
public String removePerson(#PathVariable("id") int id){
this.personService.removePerson(id);
return "redirect:/persons";
}
#RequestMapping("/edit/{id}")
public String editPerson(#PathVariable("id") int id, Model model){
model.addAttribute("person", this.personService.getPersonById(id));
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
}
/////////////////////////////////PersonDAO/////////////////////////////
package com.journaldev.spring.dao;
import java.util.List;
import com.journaldev.spring.model.Person;
public interface PersonDAO {
public void addPerson(Person p);
public void updatePerson(Person p);
public List<Person> listPersons();
public Person getPersonById(int id);
public void removePerson(int id);
}
///////////////////////////////PersonDAOImpl/////////////////////////
package com.journaldev.spring.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import com.journaldev.spring.model.Person;
#Repository
public class PersonDAOImpl implements PersonDAO {
private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
#Override
public void addPerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(p);
logger.info("Person saved successfully, Person Details="+p);
}
#Override
public void updatePerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.update(p);
logger.info("Person updated successfully, Person Details="+p);
}
#SuppressWarnings("unchecked")
#Override
public List<Person> listPersons() {
Session session = this.sessionFactory.getCurrentSession();
List<Person> personsList = session.createQuery("from Person").list();
for(Person p : personsList){
logger.info("Person List::"+p);
}
return personsList;
}
#Override
public Person getPersonById(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
logger.info("Person loaded successfully, Person details="+p);
return p;
}
#Override
public void removePerson(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
if(null != p){
session.delete(p);
}
logger.info("Person deleted successfully, person details="+p);
}
}
//////////////////////////////////Person(Model)///////////////////////
package com.journaldev.spring.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 bean with JPA annotations
* Hibernate provides JPA implementation
* #author pankaj
*
*/
#Entity
#Table(name="PERSON")
public class Person {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
private String country;
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 getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString(){
return "id="+id+", name="+name+", country="+country;
}
}
///////////////////////////////////PersonService///////////////////
package com.journaldev.spring.service;
import java.util.List;
import com.journaldev.spring.model.Person;
public interface PersonService {
public void addPerson(Person p);
public void updatePerson(Person p);
public List<Person> listPersons();
public Person getPersonById(int id);
public void removePerson(int id);
}
//////////////////////////////ServiceImpl////////////////////////////
package com.journaldev.spring.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.journaldev.spring.dao.PersonDAO;
import com.journaldev.spring.model.Person;
#Service
public class PersonServiceImpl implements PersonService {
private PersonDAO personDAO;
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
#Override
#Transactional
public void addPerson(Person p) {
this.personDAO.addPerson(p);
}
#Override
#Transactional
public void updatePerson(Person p) {
this.personDAO.updatePerson(p);
}
#Override
#Transactional
public List<Person> listPersons() {
return this.personDAO.listPersons();
}
#Override
#Transactional
public Person getPersonById(int id) {
return this.personDAO.getPersonById(id);
}
#Override
#Transactional
public void removePerson(int id) {
this.personDAO.removePerson(id);
}
}
First you have to add Jackson Databind dependency in your pom file then you can define your rest controller for exemple :
#RestController
public class PersonRestService {
#Autowired
private PersonService personService ;
#RequestMapping(value="/persons",method=RequestMethod.POST)
public Person addPerson(#RequestBody Person Person) {
return personService.addPerson(Person);
}
#RequestMapping(value="/persons",method=RequestMethod.Delete)
public void deletePerson(int code) {
personService.deletePerson(code);
}
#RequestMapping(value="/persons",method=RequestMethod.GET)
public Person getPerson(#RequestParam int code) {
return personService.getPersonById(code);
}
#RequestMapping(value="/allPersons",method=RequestMethod.GET)
public List<Person> getAllPerson() {
return personService.getAllPerson();
}
}
Its easy, what you need to do is add a response in JSON for all request which need it.
The annotation is #ResponseBody and you can return any object, jackson will serialize it to json format for you.
For example in your code:
#RequestMapping("/remove/{id}")
#ResponseBody
public boolean removePerson(#PathVariable("id") int id){
this.personService.removePerson(id);
//true if everything was OK, false if some exception
return true;
}
...
#RequestMapping(value = "/persons", method = RequestMethod.GET)
#ResponseBody
public List<Person> listPersons(Model model) {
return this.personService.listPersons();
}
You only need to modify your controller, to make it RESTFul
Also you will have to add logic to your JS code to handle the new responses values.
Simply use the annotation #RestController.
You can also refer to previously asked question on this link
Difference between spring #Controller and #RestController annotation

Resources