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")));
}
}
Related
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.
but i got this error,
2021-02-05 12:19:08.944 WARN 8168 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present]
dependencies are,
<?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.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.sample</groupId>
<artifactId>springboot-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</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-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
** Repository is,**
package com.example.sample.springboottest.Model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class User {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
}
** Controllers are,**
package com.example.sample.springboottest.Controller;
import com.example.sample.springboottest.Model.User;
import com.example.sample.springboottest.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
#Controller
#RequestMapping(path = "/demo")
public class MainController {
#Autowired
private UserRepository userRepository;
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestParam String name, #RequestParam String email){
User n =new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAllUser(){
return userRepository.findAll();
}
}
** Properties are,**
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.open-in-view=true
spring.jpa.show-sql=true
Please help me to fix this,
Since you are using #ReuestParam you can't pass JSON like what you did.
In order to pass JSON format change #RequestParam to #RequestBody as below:
#PostMapping(path = "/add")
public #ResponseBody String addNewUser(#RequestBody User user){
// User n =new User();
//
// n.setName(name);
// n.setEmail(email);
// userRepository.save(n);
userRepository.save(user);
return "Saved";
}
And postman result would be as below:
But if you need to use #RequestParam then pass query string as below:
localhost:8811/demo/add?name=upul&email=upul#gmail.com
It seems that you have mixed up #RequestParam with #RequestBody
You seem to want to POST a JSON object to your controller, in which case your method signature should be
public #ResponseBody String addNewUser(#RequestBody User user){
Required String parameter 'name' is not present
Method parameters annotated with #RequestParam are required by default. It looks like while you are calling the API, you are not passing the name query param.
Edit: In this case, we could be passing the user in the request body.
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
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);
}
}
I am new in spring
I will post my code,
that the application.properties
spring.datasource.url=jdbc:mysql://localhost/spring
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update
and this my entity
package model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
private String phone;
private String adresse;
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 getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public Person(long id, String name, String phone, String adresse) {
super();
this.id = id;
this.name = name;
this.phone = phone;
this.adresse = adresse;
}
public Person() {
super();
}
}
and this is the repository
package repositry;
import org.springframework.data.jpa.repository.JpaRepository;
import model.Person;
public interface PersonRespositry extends JpaRepository<Person, Long> {
}
and my controller
package contoller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import model.Person;
import repositry.PersonRespositry;
#RestController
public class PersonController {
PersonRespositry rp;
#Autowired
public PersonController(PersonRespositry rp) {
// TODO Auto-generated constructor stub
this.rp=rp;
}
#RequestMapping("/find")
public Person find(long id){
return rp.findOne(id);
}
#RequestMapping("/findall")
public List<Person> findall(){
return rp.findAll();
}
#RequestMapping(value="/hello")
public String Demo(){
return "Hello world !!";
}
#RequestMapping(value="/create", method=RequestMethod.GET)
public String create(){
Person p=new Person();
p.setName("med");
p.setPhone("233888");
p.setAdresse("rue ");
rp.save(p);
return " success";
}
}
This is the architect of the project:
When I run the application the database does not generate and only the
localhost:8080 is running.
Your problem is the location of the Application.java.
#ComponentScanlooks for Spring beans inside the package of the class annotated with (#SpringBootApplication contains #ComponentScan) and in subpackages of this package.
I already provided an example to a very similar setup.
Please have a look here: https://stackoverflow.com/a/27983870/2576531
Furthermore the hint of Robert Moskal is correct. The database itself has to exist already. Only the tables will be created automatically.
If you want the data to be created you need to use create or create-drop. If you are using something like mysql you'll need to have created at least the database. The tables will be created for you.
I be very careful about doing this against a production database instance.
Otherwise for me it dosen't work with #componentScan but it works now with #EntityScan(basePackages = { "com.jwt.entites" }) in the main class to scan entity classes ..
This is not the answer but this is a sample. I think this will help you
//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.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.wisdom.spring.myjdbc</groupId>
<artifactId>spring_boot_jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring_boot_jpa</name>
<description>Demo 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>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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
//application Config
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/wisdom
spring.datasource.username=root
spring.datasource.password=8855
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
server.port = 8585
package com.wisdom.spring.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wisdom.spring.model.students;
import com.wisdom.spring.repo.students_repo;
#RestController
#RequestMapping("/students")
public class studentController {
#Autowired
students_repo STDRepo;
#GetMapping(value = "/a")
public String a() {
return "hello";
}
#GetMapping(value = "/save")
public List<students> getStudents(){
System.out.println("Data returned");
return STDRepo.findAll();
}
#PostMapping(value = "/savestd")
public void saveBurger(students student) {
STDRepo.save(student);
}
}
package com.wisdom.spring.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class students {
#Id
#Column
private int s_id;
#Column
private String name;
#Column
private String address;
public students() {
}
public students(int s_id, String name, String address) {
this.s_id = s_id;
this.name = name;
this.address = address;
}
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
package com.wisdom.spring.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wisdom.spring.model.students;
public interface students_repo extends JpaRepository<students,String> {
}
package com.wisdom.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaApplication.class, args);
}
}