CORS Origin FAILED Spring Boot - java

I need you because #CROSSOrigin doesn't work and i don't understand why, you have my code here. In fact, i use WebService but i have a problem with the 'Acess-Control-Allow-Origin" i tried all but nothing had worked, please help me !!
SPRING BOOT Project with version 2.1.2 and i would like to build a REST API for ANGULAR 7
PROBLEM:
zone.js:3243 GET http://localhost:8080/apiEquipment/equipments 404
localhost/:1 Access to XMLHttpRequest at 'http://localhost:8080/apiEquipment/equipments' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
zone.js:3243 XHR failed loading: GET "http://localhost:8080/apiEquipment/equipments".
core.js:15714 ERROR
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:8080/apiEquipment/equipments", ok: false, …}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>GoSecuriServices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GoSecuriServices</name>
<description>Rest API for GoSecuri Application</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.java
package com.example.GoSecuriServices;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#EnableJpaRepositories("com.example.GoSecuriServices.repository")
#EntityScan("com.example.GoSecuriServices.model")
#ComponentScan
#SpringBootApplication
public class GoSecuriServicesApplication {
public static void main(String[] args) {
SpringApplication.run(GoSecuriServicesApplication.class, args);
}
}
Equipment.java (my table)
package model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
#Entity
#Table(name = "Equipment")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public class Equipment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Equipment_id;
#NotBlank
private String EquipmentName;
#NotBlank
private Integer Nb;
// Getters and Setters
public Long getEquipment_id() {
return this.Equipment_id;
}
public void SetEquipment_id(Long id) {
this.Equipment_id = id;
}
public String getEquipmentName() {
return this.EquipmentName;
}
public void setEquipmentName(String name) {
this.EquipmentName = name;
}
public Integer getNb() {
return this.Nb;
}
public void setNb(Integer nb) {
this.Nb = nb;
}
}
EquipmentRepository.java
package repository;
import model.Equipment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface EquipmentRepository extends JpaRepository<Equipment, Long> {
}
EquipmentController.java
package controller;
import exception.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import model.Equipment;
import repository.EquipmentRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
#RestController
#CrossOrigin(origins = "*", allowedHeaders = "*", maxAge = 3600)
#RequestMapping("/apiEquipment")
public class EquipmentController {
#Autowired
EquipmentRepository equipmentRepository;
#RequestMapping(value= "/apiEquipment/**", method=RequestMethod.OPTIONS)
public void corsHeaders(HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
response.addHeader("Access-Control-Max-Age", "3600");
}
// Get all equipments
#GetMapping("/equipments")
public List<Equipment> getAllEquipments() {
return equipmentRepository.findAll();
}
// Create new equipment
#PostMapping("/equipments")
public Equipment createEquipment(#Valid #RequestBody Equipment equipment) {
return equipmentRepository.save(equipment);
}
// Get a single equipment
#GetMapping("/equipments/{id}")
public Equipment getEquipmentById(#PathVariable(value = "id") Long equipmentId) {
return equipmentRepository.findById(equipmentId)
.orElseThrow(() -> new ResourceNotFoundException("Equipment", "id", equipmentId));
}
// Update a Equipment
#PutMapping("/equipments/{id}")
public Equipment updateNote(#PathVariable(value = "id") Long equipmentId,
#Valid #RequestBody Equipment equipmentDetails) {
Equipment equipment = equipmentRepository.findById(equipmentId)
.orElseThrow(() -> new ResourceNotFoundException("Equipment", "id", equipmentId));
equipment.setEquipmentName(equipmentDetails.getEquipmentName());
equipment.setNb(equipmentDetails.getNb());
Equipment updatedEquipment = equipmentRepository.save(equipment);
return updatedEquipment;
}
// Delete a Equipment
#DeleteMapping("/equipments/{id}")
public ResponseEntity<?> deleteEquipment(#PathVariable(value = "id") Long equipmentId) {
Equipment equipment = equipmentRepository.findById(equipmentId)
.orElseThrow(() -> new ResourceNotFoundException("Equipment", "id", equipmentId));
equipmentRepository.delete(equipment);
return ResponseEntity.ok().build();
}
}

Did you read the CORS Support section in Spring Documentation?
You can also try to use Spring Higher-Order Components and #EnableCORS or if you don't want to use additional dependency use #Bean from here

You need to configure a web cross-domain configuration as follows:
package com.liukai.routermanagement.config;
import com.liukai.routermanagement.interceptor.LoginHandlerInterceptor;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
#SpringBootConfiguration
public class MyWebMvcConfig extends WebMvcConfigurationSupport {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login","/router/login","/user/registered");
super.addInterceptors(registry);
}
// this main mothod,Just add this method
#Override
protected void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods("GET","POST","PUT","DELETE");
super.addCorsMappings(registry);
}
}

Related

POST/PUT/DELETE doesn't shown in swagger springboot

it's my swagger Config file
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import static springfox.documentation.builders.PathSelectors.regex;
#Configuration
#EnableSwagger2
public class SwaggerConfiguration {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("example.com"))
.paths(regex("/product.*"))
.build()
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfo(
"Spring Boot REST API",
"Spring Boot REST API for Online",
"1.0",
"Terms of service",
new Contact("Example Example", "https://springframework.guru/about/", "example#gmail.com"),
"Apache License Version 2.0",
"https://www.apache.org/licenses/LICENSE-2.0");
}
}
Student Controller
import java.util.List;
import java.util.Optional;
import com.example.learnspring.StudentRepository.StudentRepository;
import com.example.learnspring.model.StudentDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
#RestController
public class StudentController {
#Autowired
private StudentRepository eRepo;
#PostMapping("/employees")
public StudentDto save (#RequestBody StudentDto employee) {
return eRepo.save(employee);
}
//#RequestMapping("/greeting/{lang}")
#RequestMapping(value = "/greeting/{lang}", method = RequestMethod.GET)
#GetMapping("/student")
public List<StudentDto> get () {
return eRepo.findAll();
}
#GetMapping("/student/{id}")
public StudentDto get (#PathVariable int id) {
Optional<StudentDto> employee = eRepo.findById(id);
if (employee.isPresent()) {
return employee.get();
}
throw new RuntimeException("Not found for the id "+id);
}
#PutMapping("/student/{id}")
public StudentDto update (#PathVariable int id, #RequestBody StudentDto employee) {
employee.setId(id);
return eRepo.save(employee);
}
#DeleteMapping("/student/{id}")
public ResponseEntity<HttpStatus> delete (#PathVariable int id) {
eRepo.deleteById(id);
return new ResponseEntity<HttpStatus>(HttpStatus.NO_CONTENT);
}
}
StudentDTO class
import lombok.*;
import lombok.experimental.FieldDefaults;
import javax.persistence.*;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "student")
#Setter
#Getter
#NoArgsConstructor
#Data
#FieldDefaults(level= AccessLevel.PRIVATE)
public class StudentDto {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private int id;
#Column(name = "name")
#NotNull(message = "Name cannot be null")
private String name;
#Column(name = "age")
#NotNull(message = "Age cannot be null")
#Min(value = 15, message = "Age should not be less than 15")
#Max(value = 65, message = "Age should not be greater than 65")
private int age;
public String getName() {
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age){
this.age=age;
}
}
My Repository
import com.example.learnspring.model.StudentDto;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface StudentRepository extends JpaRepository<StudentDto, Integer> {
}
Myapplication class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication
#EnableSwagger2
public class LearnSpringApplication {
public static void main(String[] args) {
SpringApplication.run(LearnSpringApplication.class, args);
}
}
application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver
server.port=9090
spring.jpa.hibernate.ddl-auto=update
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>LearnSpring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>LearnSpring</name>
<description>LearnSpring</description>
<properties>
<java.version>18</java.version>
<swagger.version>3.0.0</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--springfox dependencies for api documentations in swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.ivy</groupId>
<artifactId>ivy</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.project-lombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
When I run this application everything looks fine but I can't see the POST/PUT/or DELETE. I try to many things I find from Internet but it doesn't work. I new on this topic. I actually want to wrote null inputs and get exceptions for exception handling.
So your Docket Configuration has specified a regex pattern for product
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("example.com"))
.paths(regex("/product.*"))
.build()
.apiInfo(metaData());
}
But your controllers don't have any APIs with /product.
Thus you're not able to see APIs in swagger documentation.
Try with below configuration and see if it shows you all endpoints and then start working around regex configurations.
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
Above configuration matches all the API paths in your web application basically anywhere.
You can access your APIs at
Change the APPLICATION_PORT and CONTEXT-PATH
http://localhost:{{APPLICATION_PORT}}/{{CONTEXT-PATH}}/swagger-ui.html

Class SpringHibernateJpaPersistenceProvider does not implement the requested interface PersistenceProvider

I'm stumped - I haven't used Hibernate in several years and then, never with Spring Boot. Spring Boot but never with Hibernate or JPA. So i'm trying to figure out how to get this to work for my job - I'm supposed to demo something Monday and if I can get 'this' to work, I'll copy it over to my work laptop and change the details of course. Btw - here's the message I get - I had to shorten it in the title:
"Class org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider does not implement the requested interface javax.persistence.spi.PersistenceProvider"
I have the "main" class - TestWebApplication:
package net.draconia.testWeb;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
#SpringBootApplication(scanBasePackages = {"com.draconia.testWeb.controller"})
public class TestWebApplication
{
#Bean
public DataSource getDatasource()
{
BasicDataSource objDatasource = new BasicDataSource();
objDatasource.setDriverClassName("com.mysql.jdbc.Driver");
objDatasource.setUrl("jdbc:mysql://localhost:3306/Test");
objDatasource.setUsername("root");
objDatasource.setPassword("R3g1n# M1lL$ 1$ My Qu3eN!");
return(objDatasource);
}
#Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory()
{
LocalContainerEntityManagerFactoryBean objEntityManager = new LocalContainerEntityManagerFactoryBean();
objEntityManager.setDataSource(getDatasource());
objEntityManager.setPackagesToScan(new String[] { "net.draconia.testWeb.beans" });
JpaVendorAdapter objVendorAdapter = new HibernateJpaVendorAdapter();
objEntityManager.setJpaVendorAdapter(objVendorAdapter);
objEntityManager.setJpaProperties(getHibernateProperties());
return(objEntityManager);
}
protected Properties getHibernateProperties()
{
Properties objHibernateProperties = new Properties();
objHibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
objHibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
return(objHibernateProperties);
}
#Bean
public JpaTransactionManager getHibernateTransactionManager()
{
JpaTransactionManager objTransactionManager = new JpaTransactionManager();
objTransactionManager.setEntityManagerFactory(getEntityManagerFactory().getObject());
return(objTransactionManager);
}
public static void main(String[] args)
{
SpringApplication.run(TestWebApplication.class, args);
}
}
, the entity bean:
package net.draconia.testWeb.beans;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity(name = "Books")
public class Book
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer miId;
#Column(columnDefinition = "varchar(200) not null", insertable = true, length = 200, name = "BookName", nullable = false, table = "Books", unique = false, updatable = true)
private String msBookName;
#Column(columnDefinition = "varchar(100) not null", insertable = true, length = 100, name="Author", nullable = false, table = "Books", unique = false, updatable = true)
private String msAuthor;
public String getAuthor()
{
if(msAuthor == null)
msAuthor = "";
return(msAuthor);
}
public String getBookName()
{
if(msBookName == null)
msBookName = "";
return(msBookName);
}
public int getId()
{
if(miId == null)
miId = 0;
return(miId);
}
public void setAuthor(final String sAuthor)
{
if(sAuthor == null)
msAuthor = "";
else
msAuthor = sAuthor;
}
public void setBookName(final String sBookName)
{
if(sBookName == null)
msBookName = "";
else
msBookName = sBookName;
}
public void setId(final Integer iId)
{
if(iId == null)
miId = 0;
else
miId = iId;
}
}
, the DAOConcrete class (the interface is just one method which is logical but if you want I'll post that too):
package net.draconia.testWeb.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import net.draconia.testWeb.beans.Book;
#Repository("bookDAO")
public class BookDAOImpl implements BookDAO
{
#Autowired
private EntityManagerFactory mObjEntityManagerFactory;
public List<Book> getAllBooks()
{
EntityManager objEntityManager = getEntityManagerFactory().createEntityManager();
List<Book> lstBooks = objEntityManager.createQuery("from Books", Book.class).getResultList();
return(lstBooks);
}
protected EntityManagerFactory getEntityManagerFactory()
{
return(mObjEntityManagerFactory);
}
}
, and the Controller class for the REST endpoints/MVC Controller:
package net.draconia.testWeb.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import net.draconia.testWeb.beans.Book;
import net.draconia.testWeb.dao.BookDAO;
#Controller
public class TestController
{
#Autowired
private BookDAO mObjDAO;
#GetMapping("/Books")
public List<Book> getBooks()
{
return(getDAO().getAllBooks());
}
protected BookDAO getDAO()
{
return(mObjDAO);
}
}
The POM file is here just for completeness but I don't think it's necessarily a problem unless I'm missing a dependency:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>net.draconia</groupId>
<artifactId>testWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testWeb</name>
<description>Demo project for Spring Boot</description>
<properties>
<hibernate.version>6.1.0.Final</hibernate.version>
<java.version>11</java.version>
<mysql.version>8.0.29</mysql.version>
<spring.version>5.3.2</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
If you'll note, i'm including a dependency for the Jackson library because the list of books should return as a JSON object. I don't think that's a poblem but just saying - and I could probably have remoed that for this but then when it runs, the list of books would be unintelligible to me getting a response when/if it worked. What am I doing wrong???
Change hibernate to version 5.6.9.Final (or any higher 5.6.x):
<hibernate.version>5.6.9.Final</hibernate.version>

Parameter 0 of constructor in com.****.Controller requires a bean of type 'com.*****. service'. Spring boot application wont run

My code:
package com.qa.project.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#EnableJpaRepositories
#ComponentScan
#SpringBootApplication
#Entity
public class RunStat {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
#NotBlank
private double runTime;
#Column
#NotBlank
private double runDistance;
#Column
#NotBlank
private int runCalories;
public RunStat() {
}
public RunStat(Long id, int runCalories, double runDistance, double runTime) {
this.id = id;
this.runCalories = runCalories;
this.runDistance = runDistance;
this.runTime = runTime;
}
public RunStat(int runCalories, double runDistance, double runTime) {
this.runCalories = runCalories;
this.runDistance = runDistance;
this.runTime = runTime;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public double getRunTime() {
return runTime;
}
public void setRunTime(double runTime) {
this.runTime = runTime;
}
public double getRunDistance() {
return runDistance;
}
public void setRunDistance(double runDistance) {
this.runDistance = runDistance;
}
public int getRunCalories() {
return runCalories;
}
public void setRunCalories(int runCalories) {
this.runCalories = runCalories;
}
}
package com.qa.project.service;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Service;
import com.qa.project.domain.RunStat;
import com.qa.project.repository.RunStatRepo;
#Service
public class RunStatService {
private RunStatRepo repo;
public RunStatService(RunStatRepo repo) {
this.repo = repo;
}
public RunStat addStats(RunStat stats) {
return this.repo.save(stats);
}
public List<RunStat> getAllStats(){
return this.repo.findAll();
}
public RunStat updateStats(Long id, RunStat newStats) {
Optional<RunStat> optionalRunStat = this.repo.findById(id);
if (optionalRunStat.isPresent()) {
RunStat existingRunStat = optionalRunStat.get();
existingRunStat.setRunTime(newStats.getRunTime());
existingRunStat.setRunDistance(newStats.getRunDistance());
existingRunStat.setRunCalories(newStats.getRunCalories());
return this.repo.save(existingRunStat);
}
return null;
}
public boolean removeStats(Long id) {
this.repo.deleteById(id);
return !this.repo.existsById(id);
}
public RunStat readById(Long id){
Optional<RunStat> optionalRunStat = this.repo.findById(id);
//if (optionalRunStat.isPresent()) { //get rid of this line but use for other methods later
return optionalRunStat.get();
}
}
package com.qa.project.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import com.qa.project.domain.RunStat;
import com.qa.project.service.RunStatService;
#Component
#Repository
public interface RunStatRepo extends JpaRepository<RunStat, Long>{
public RunStat addStats(RunStat stats);
public List<RunStat> getAllStats();
public RunStat updateStats(Long id, RunStat newStats);
public boolean removeStats(Long id);
public Optional<RunStat> findById(Long id);
}
package com.qa.project.rest;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.qa.project.domain.RunStat;
import com.qa.project.service.RunStatService;
#RestController
public class RunStatController {
private RunStatService service;
public RunStatController(RunStatService service) {
super();
this.service = service;
}
#PostMapping("/createStats")
public RunStat addStats(#RequestBody RunStat stats) {
return this.service.addStats(stats);
}
#GetMapping("/getStats")
public List<RunStat> getAllStats(){
return this.service.getAllStats();
}
#DeleteMapping("/removeStats/{id}")
public boolean removeStats(#PathVariable Long id) {
return this.service.removeStats(id);
}
#GetMapping("/getAUser/{id}")
public RunStat readById(#PathVariable Long id){
return this.service.readById(id);
}
#PutMapping("/editUser/{id}") //changes whole record, so you have to input whole new record to replace
public RunStat updateStats(#PathVariable Long id, #RequestBody RunStat stats) {
return this.service.updateStats(id, stats);
}
}
package com.qa.project;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.context.annotation.Bean;
#EnableAutoConfiguration
#SpringBootApplication(scanBasePackages={"com.qa.service","com.qa.project.domain", "com.qa.project.rest", "com.qa.repository"})
public class QaProjectApplication {
public static void main(String[] args) {
SpringApplication.run(QaProjectApplication.class, args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.qa</groupId>
<artifactId>QaProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>QaProject</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The main problem here is the wrongly placed #SpringBootApplication. A Spring Boot application has a main start class which bootstraps the whole application. This class should get the mentioned annotation. It is a special annotation that also already includes component scanning.
By default, components are scanned only in the same package, where that annotation is found, and in its sub-packages. You have placed the annotation onto your class RunStat in the package com.qa.project.domain. Thus, all components in other packages - such as com.qa.project.service - are not found.
The solution:
Create a class with the name RunStatApplication (or similar) and place it into the package com.qa.project. That class gets the annotation #SpringBootApplication. With that setup, all other components are now in sub-packages and thus are found.

Issue with Spring Boot Validation with version 2.5.5

I am fairly new to Spring Boot and it's various libraries. I am particularly trying Validation. I have added Validation annotations to UserDto class. When I send createUser request with invalid email, I get success. None of the validations work.
I have tried using Hibernate-Validator dependancy as well.
See below the code.
The UserDto class:
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public class UserDto {
#NotNull
#Min(value=5)
#Max(value=10)
private String name;
#NotNull
#Min(value=3)
#Max(value=50)
private String password;
#Email
private String email;
public UserDto(String name, String password, String email) {
super();
this.name = name;
this.password = password;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
The UserCotroller:
import javax.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
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.user.test.dto.UserDto;
#RestController
#RequestMapping("/users")
public class UserController {
#PostMapping
public ResponseEntity<String> createUser(#Valid #RequestBody UserDto userDto, Errors errors){
System.out.println(userDto.toString());
System.out.println(errors.toString());
String response = "success";
return ResponseEntity.ok(response);
}
}
Driver Class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.user</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here is the Postman Request, which gives "success".
{
"name": "Username",
"password":"username#123",
"email":"username"
}
I could find two issues in your code:
The #Min/#Max annotations are for numeric values, to set the range of numeric values (not the number of strings); so these do not work for Strings. Please remove them and find alternatives (e.g. #Size).
You need to map the userDto object to the model in your controller with the #ModelAttribute annotation.
Controller (further edited to accommodate different responses)
#PostMapping
public ResponseEntity<String> createUser(#ModelAttribute #Valid #RequestBody UserDto userDto,Errors errors){
System.out.println(userDto.toString());
System.out.println(errors.toString());
if (errors.hasErrors()) {
return ResponseEntity.badRequest().body("Errors exist");
}
return ResponseEntity.ok("Success");
}
}
UserDto
public class UserDto {
#NotNull
#Size(min=5, max= 10)
private String name;
#NotNull
#Size(min=3, max= 50)
private String password;
#Email
private String email;
// rest of the code
}
Tests for controller
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#SpringBootTest
#ExtendWith(MockitoExtension.class)
class UserControllerTest {
MockMvc mockMvc;
#Autowired
UserController userController;
#BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
#Test
void emailInvalid() throws Exception {
mockMvc.perform(post("/users").param("name", "uname")
.param( "password", "LongPasswordHere")
.param( "email", "email")).andExpect(status().isBadRequest())
.andExpect(content().string(containsString("Errors exist")));
}
#Test
void emailValid() throws Exception {
mockMvc.perform(post("/users").param("name", "uname")
.param( "password", "LongPasswordHere")
.param( "email", "email#gmail.com")).andExpect(status().isOk())
.andExpect(content().string(containsString("Success")));
}
}

Need Help! Spring Boot error: Unsatisfied DependancyException: Error creating bean with name ''

I can not figure out this error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'restapiApplication': Unsatisfied dependency expressed through method 'productRepository' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.murphy.demo.model.Product com.murphy.demo.repository.ProductRepository.findOne(java.lang.String)! No property findOne found for type Product!
Here is my Repository in package:
package com.murphy.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import com.murphy.demo.model.Product;
#Repository
public interface ProductRepository extends JpaRepository<Product,String> {
Product findOne(String id);
}
package com.murphy.demo.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
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.RestController;
import com.murphy.demo.model.Product;
import com.murphy.demo.repository.ProductRepository;
#RestController
#RequestMapping(path ="/api/products/" )
public class ProductsController {
private ProductRepository productRepository;
#Autowired
public void productRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
#RequestMapping(path ="{id}", method = RequestMethod.GET)
public Product getProduct(#PathVariable(name = "id") String id) {
return productRepository.findOne(id);
}
}
Product.java in package
package com.murphy.demo.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator ="system-uuid")
#GenericGenerator(name ="system-uuid",strategy ="uuid")
private String id;
private String name;
private String description;
private String category;
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
main application:
package com.murphy.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.murphy.demo.model.Product;
import com.murphy.demo.repository.ProductRepository;
#SpringBootApplication
public class RestapiApplication implements CommandLineRunner{
private ProductRepository productRepository;
#Autowired
public void productRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public static void main(String[] args) {
SpringApplication.run(RestapiApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
Product test = new Product();
test.setName("test");
test.setDescription("test");
test.setCategory("general");
test.setType("null");
productRepository.save(test);
}
}
Pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.murphy.demo</groupId>
<artifactId>restapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restapi</name>
<description> project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.properites is as follows:
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:file:~/Products;IFEXISTS=FALSE;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.path=/h2-console
spring.jpa.show-sql= true
Ive tried everything I can think of, Any suggestions at all will be helpful.
Thanks!
By naming your method "findOne" the Spring Data JPA is trying to create a query to search by for the property "findOne" in your Product Class, which doesn't exist, hence the error "No property findOne found for type Product". You should specify the name of the property you are searching for. In your case: findOneById (String id) will create a query to find one object by the Id property.
For more information on how to name your methods to create the correct queries you can read the documentation about this topic.
Why don't you use CrudRepository instead of JpaRepository? findOne(id) will be automatically available. That way your repository interface whould just be empty.
https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html

Categories

Resources