我正在尝试使用 Spring 开发一个项目,并且我正在尝试为此下载“Swagger-ui”。但我总是遇到问题。我将在下面与您分享我遇到的错误,并分别与您分享我的 pom.xml、application.properties 和 application.java 文件。我使用 postgresql 作为数据库,并且我确定密码是正确的。
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
这只是我收到的错误之一。当我对其进行一些更改时,错误可能会变成这样。
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.plugin.core.support.AbstractTypeAwareSupport$BeansOfTypeTargetSource.<init>(AbstractTypeAwareSupport.java:135)
The following method did not exist:
'void org.springframework.util.Assert.notNull(java.lang.Object)'
The calling method's class, org.springframework.plugin.core.support.AbstractTypeAwareSupport$BeansOfTypeTargetSource, was loaded from the following location:
jar:file:/C:/Users/emirg/.m2/repository/org/springframework/plugin/spring-plugin-core/1.2.0.RELEASE/spring-plugin-core-1.2.0.RELEASE.jar!/org/springframework/plugin/core/support/AbstractTypeAwareSupport$BeansOfTypeTargetSource.class
The called method's class, org.springframework.util.Assert, is available from the following locations:
jar:file:/C:/Users/emirg/.m2/repository/org/springframework/spring-core/6.1.12/spring-core-6.1.12.jar!/org/springframework/util/Assert.class
The called method's class hierarchy was loaded from the following locations:
org.springframework.util.Assert: file:/C:/Users/emirg/.m2/repository/org/springframework/spring-core/6.1.12/spring-core-6.1.12.jar
Action:
Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.plugin.core.support.AbstractTypeAwareSupport$BeansOfTypeTargetSource and org.springframework.util.Assert
我的 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>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>kodlamaio</groupId>
<artifactId>northwind</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>northwind</name>
<description>Demo project for Spring Boot</description>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</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>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</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>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
我的应用程序.属性页面
spring.application.name=northwind
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://localhost:5432/Northwind
spring.datasource.username=*****
spring.datasource.password=*****
spring.jpa.properties.javax.persistence.validation.mode = none
spring.datasource.driver-class-name=org.postgresql.Driver
spring.profiles.active=dev
我的 NorthwindApplication.java 页面
package kodlamaio.northwind;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableSwagger2
public class NorthwindApplication {
public static void main(String[] args) {
SpringApplication.run(NorthwindApplication.class, args);
}
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("kodlamaio.northwind"))
.build();
}
}
我的ProductsController.java页面
package kodlamaio.northwind.api.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import kodlamaio.northwind.business.abstracts.ProductService;
import kodlamaio.northwind.entities.concretes.Product;
@RestController
@RequestMapping("/api/products")
public class ProductsController {
@Autowired
public ProductsController(ProductService productService) {
super();
this.productService = productService;
}
private ProductService productService;
@GetMapping("/getall")
public List<Product> getAll(){
return this.productService.getAll();
}
}
然后我决定尝试一些不同的东西,并决定使用 openapi-ui 并将以下内容添加到我的 pom.xml 文件中。
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
但是这次我在 localhost:8080 端口上遇到以下错误。
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Sep 01 16:06:17 TRT 2024
There was an unexpected error (type=Not Found, status=404).
No static resource swagger-ui.html.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource swagger-ui.html.
我知道我的 spring 文件夹和我编写的代码不匹配。但我不知道如何修复它,ChatGPT 根本没有帮助。
一次打一个球。一次测试一个函数,直到它可以执行。然后添加第二个功能。
最小可测试 Spring Boot + JPA + Swapper Doc API 示例:
demo-jpa
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ ├── DemoJpaApplication.java
│ ├── WebConfig.java
│ ├── HelloController.java
│ ├── model
│ │ └── Person.java
│ ├── controller
│ │ └── PersonController.java
│ ├── repository
│ │ └── PersonRepository.java
│ └── service
│ └── PersonService.java
└── resources
├── application.properties
└── data.sql
spring.application.name=demo-jpa
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.sql.init.mode=always
spring.datasource.initialization-mode=always
# http://localhost:8080/h2-console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# swagger
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.api-docs.path=/api-docs
CREATE TABLE IF NOT EXISTS PERSON (
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(255),
MAIL VARCHAR(255)
);
INSERT INTO PERSON (NAME, MAIL) VALUES ('John Doe', '[email protected]');
INSERT INTO PERSON (NAME, MAIL) VALUES ('Jane Doe', '[email protected]');
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoJpaApplication {
public static void main(String[] args) {
SpringApplication.run(DemoJpaApplication.class, args);
}
}
package com.example;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
@Configuration
@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO)
public class WebConfig {
}
不是 JPA
package com.example;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello/{name}")
public String sayHello(
@PathVariable String name,
@RequestParam(value = "greeting", defaultValue = "Hello") String greeting) {
return String.format("%s, %s!", greeting, name);
}
}
package com.example.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Schema(hidden = true)
private Long id;
private String name;
private String mail;
// Constructors, getters, and setters
public Person() {
}
public Person(String name, String mail) {
this.name = name;
this.mail = mail;
}
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 getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
package com.example.controller;
import com.example.model.Person;
import com.example.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@RestController
@RequestMapping("/persons")
public class PersonController {
@Autowired
private PersonService personService;
@GetMapping
public Page<Person> getAllPersons(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) {
return personService.getAllPersons(page, size);
}
@GetMapping("/{id}")
public Optional<Person> getPersonById(@PathVariable Long id) {
return personService.getPersonById(id);
}
@PostMapping
public Person createPerson(@RequestBody Person person) {
return personService.savePerson(person);
}
@PutMapping("/{id}")
public Person updatePerson(@PathVariable Long id, @RequestBody Person updatedPerson) {
Optional<Person> optionalPerson = personService.getPersonById(id);
if (optionalPerson.isPresent()) {
Person person = optionalPerson.get();
person.setName(updatedPerson.getName());
person.setMail(updatedPerson.getMail());
return personService.savePerson(person);
} else {
throw new RuntimeException("Person not found");
}
}
@DeleteMapping("/{id}")
public void deletePerson(@PathVariable Long id) {
personService.deletePerson(id);
}
}
package com.example.service;
import com.example.model.Person;
import com.example.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class PersonService {
@Autowired
private PersonRepository personRepository;
public Page<Person> getAllPersons(int page, int size) {
return personRepository.findAll(PageRequest.of(page, size));
}
public Optional<Person> getPersonById(Long id) {
return personRepository.findById(id);
}
public Person savePerson(Person person) {
return personRepository.save(person);
}
public void deletePerson(Long id) {
personRepository.deleteById(id);
}
}
package com.example.repository;
import com.example.model.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface PersonRepository extends JpaRepository<Person, Long>, PagingAndSortingRepository<Person, Long> {
}
mvn clean package
java -jar target/demojpa.jar
打开http://localhost:8080/swagger-ui/index.html