我有一个简单的 PUT 请求,它在本地 h2 数据库中连续保存一本书。使用邮递员,当我先发送请求,然后再发送请求时,它会返回 401 错误 - 没有数据。截图:1:。但是,如果我一个接一个地执行请求(GET 请求,成功执行)
,PUT 请求返回 403 禁止错误
。我使用本地 h2 内存数据库,并使用此代码填充它(我还设置了一个架构 - 否则它无法识别表名):
DROP TABLE IF EXISTS BOOKS;
CREATE TABLE BOOKS(
isbn LONG AUTO_INCREMENT PRIMARY KEY,
count_books INT NOT NULL,
author VARCHAR(30) NOT NULL,
name VARCHAR(30) NOT NULL UNIQUE,
description VARCHAR(250)
);
INSERT INTO BOOKS (count_books, author, name, description) VALUES
(2,'Иван Вазов', 'Под Игото', 'В малко градче пристига странник и им показва значението на свободата'),
(4,'Тютюн', 'Димитър Димов', 'История за човешки характери, поквара и любов на фона на ВСВ.'),
(6,'Клетниците', 'Виктор Юго', 'Разтърсваща история за човешкия падеж и неговото възстановяване.');
至于 Rest API,我使用 Spring Boot,以及 Web、H2、PostGre 和 OAuth 2.0(未来)。这是我的服务类(充当 DAO):
package Library.demo.dao;
import Library.demo.entities.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.LinkedList;
@Service
public class BooksDAOImpl {
@Autowired
BookRepository bookRepository;
public LinkedList<Books> get_all_books() {
LinkedList<Books> books = new LinkedList<>();
for(Books book : bookRepository.findAll()) {
books.add(book);
}
System.out.println(bookRepository.count());
return books;
}
public void addBook_admin(int count, String name, String author, String description){
Books book = new Books(count,name, author,description);
bookRepository.save(book);
System.out.println(bookRepository.count());
}
}
这是我的 REST 控制器类,用于向数据库添加书籍:
package Library.demo.command;
import Library.demo.dao.BooksDAOImpl;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.exception.JDBCConnectionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import java.util.InputMismatchException;
@RestController
public class Add_book_admin_command {
@Autowired
BooksDAOImpl bookDAO;
@PutMapping("/books/add")
public void execute(@RequestParam int count_books, @RequestParam String author, @RequestParam String name, @RequestParam String description) {
try {
bookDAO.addBook_admin(count_books, author, name, description);
}catch (InputMismatchException ime){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Wrong type of information");
}catch (JDBCConnectionException jdbcConnectionException){
throw new ResponseStatusException(HttpStatus.BAD_GATEWAY, "Error connecting to database");
}catch (NonUniqueObjectException objectException){
throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "Book already exists");
}
}
}
这是我获取所有书籍的控制器:
package Library.demo.command;
import Library.demo.dao.BooksDAOImpl;
import Library.demo.entities.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;
@RestController
public class List_all_books_admin_command {
@Autowired
BooksDAOImpl bookDAO;
@GetMapping("/books/all")
public LinkedList<Books> execute() {
return bookDAO.get_all_books();
}
}
还有我的 application.settings 文件:
spring.datasource.url=jdbc:h2:mem:test;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.hibernate.ddl-auto=none
security.basic.enable= false
security.ignored=/**
我的实体类是书籍:
package Library.demo.entities;
import javax.persistence.*;
@Entity(name = "BOOKS")
public class Books {
@Id
@GeneratedValue
private long isbn;
private int count_books;
private String author;
private String name;
private String description;
public Books( int count_books, String author, String name, String description) {
this.count_books = count_books;
this.author = author;
this.name = name;
this.description = description;
}
public Books() {
}
public long getIsbn() {
return isbn;
}
public void setIsbn(int isbn) {
this.isbn = isbn;
}
public int getCount() {
return count_books;
}
public void setCount(int count) {
this.count_books = count;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
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;
}
}
程序构建得很好,控制台输出中没有异常,即使 PUT 请求失败。我对 Spring 框架还很陌生,因此将不胜感激 :)
答案 0 :(得分:0)
答案 - 通过 WebSecurityConfig 类关闭 csrf。 代码片段:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
http.cors().and().csrf().disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
应该可以解决问题