我是Spring框架的新手,正在尝试创建
Spring-Boot
与…结合
JSP
制作一个小的网络应用。然而,当我运行程序时,我得到以下错误。
完整堆栈跟踪:
2022-01-01 15:31:43.790 INFO 20116 --- [ restartedMain] spring.jsp.JspApplication : Starting JspApplication using Java 11.0.13 on cudayanh with PID 20116 (C:\Users\PC_1\Desktop\java_spring\spring-boot-jsp\jsp\target\classes started by PC_1 in C:\Users\PC_1\desktop\java_spring\spring-boot-jsp\jsp)
2022-01-01 15:31:43.791 INFO 20116 --- [ restartedMain] spring.jsp.JspApplication : No active profile set, falling back to default profiles: default
2022-01-01 15:31:43.916 INFO 20116 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-01-01 15:31:43.917 INFO 20116 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-01-01 15:31:47.098 INFO 20116 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-01 15:31:47.112 INFO 20116 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-01 15:31:47.112 INFO 20116 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-01 15:31:47.115 WARN 20116 --- [ restartedMain] o.a.catalina.core.AprLifecycleListener : This listener must only be nested within Server elements, but is in [TomcatEmbeddedContext].
2022-01-01 15:31:47.115 INFO 20116 --- [ restartedMain] o.a.catalina.core.AprLifecycleListener : Loaded Apache Tomcat Native library [1.2.31] using APR version [1.7.0].
2022-01-01 15:31:47.116 INFO 20116 --- [ restartedMain] o.a.catalina.core.AprLifecycleListener : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true].
2022-01-01 15:31:47.116 INFO 20116 --- [ restartedMain] o.a.catalina.core.AprLifecycleListener : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2022-01-01 15:31:47.123 INFO 20116 --- [ restartedMain] o.a.catalina.core.AprLifecycleListener : OpenSSL successfully initialized [OpenSSL 1.1.1l 24 Aug 2021]
2022-01-01 15:31:47.499 INFO 20116 --- [ restartedMain] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2022-01-01 15:31:47.515 INFO 20116 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-01 15:31:47.515 INFO 20116 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3596 ms
2022-01-01 15:31:47.623 WARN 20116 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookController' defined in file [C:\Users\PC_1\Desktop\java_spring\spring-boot-jsp\jsp\target\classes\spring\jsp\controllers\BookController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookServiceImpl': Unsatisfied dependency expressed through field 'bookRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'spring.jsp.repositories.BookRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value="spring.jsp.repositories.BookRepository")}
2022-01-01 15:31:47.626 INFO 20116 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-01-01 15:31:47.653 INFO 20116 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-01-01 15:31:47.713 ERROR 20116 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field bookRepository in spring.jsp.services.impl.BookServiceImpl required a bean of type 'spring.jsp.repositories.BookRepository' that could not be found.
The following candidates were found but could not be injected:
- User-defined bean
- User-defined bean method 'provideBookRepository' in 'JspConfiguration'
Action:
Consider revisiting the entries above or defining a bean of type 'spring.jsp.repositories.BookRepository' in your configuration.
我试图通过引用和使用其他人提供的一系列解决方案来解决这个问题,比如添加
@Service
,
@Repository
到实现类。然而,它们都不起作用。
repositories/BookRepository.java
public interface BookRepository {
Collection<Book> findAll();
Optional<Book> findById(String isbn);
Book add(Book book);
}
repositories/impl/InMemoBookRepositoryImpl.java
@Service
@Primary
public class InMemoBookRepositoryImpl implements BookRepository {
@Autowired
private final Map<String, Book> booksStore;
public InMemoBookRepositoryImpl(Map<String, Book> booksStore) {
this.booksStore = booksStore;
this.booksStore.putAll(booksStore);
}
@Override
public Collection<Book> findAll() {
if (this.booksStore.isEmpty()) {
return Collections.emptyList();
}
return booksStore.values();
}
@Override
public Optional<Book> findById(String isbn) {
return Optional.ofNullable(booksStore.get(isbn));
}
@Override
public Book add(Book book) {
booksStore.put(book.getIsbn(), book);
return book;
}
}
services/BookService.java
public interface BookService {
Collection<BookDTO> getBooks();
BookDTO addBook(BookDTO book);
}
services/impl/BookServiceImpl.java
@Service
@Primary
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("spring.jsp.repositories.BookRepository")
private final BookRepository bookRepository;
public BookServiceImpl(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@Override
public Collection<BookDTO> getBooks() {
return bookRepository.findAll()
.stream()
.map(BookServiceImpl::convertBookDto)
.collect(Collectors.toList());
}
@Override
public BookDTO addBook(BookDTO bookDto) {
final Optional<Book> existingBook = bookRepository.findById(bookDto.getIsbn());
if (existingBook.isPresent()) {
throw new DuplicateBookException(bookDto);
}
final Book savedBook = bookRepository.add(convertToBook(bookDto));
return convertBookDto(savedBook);
}
private static BookDTO convertBookDto(Book book) {
return new BookDTO(book.getIsbn(), book.getName(), book.getAuthor());
}
private static Book convertToBook(BookDTO bookDto) {
return new Book(bookDto.getIsbn(), bookDto.getName(), bookDto.getAuthor());
}
}
controllers/BookController.java
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("spring.jsp.services.bookService")
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping("/books")
public String getBooks(Model model) {
model.addAttribute("books", this.bookService.getBooks());
return "booksList";
}
@GetMapping("/addBook")
public String addBook(Model model) {
model.addAttribute("book", new Book());
return "addBook";
}
@PostMapping("/addBook")
public RedirectView addBook(@ModelAttribute("book") BookDTO bookDto, RedirectAttributes redirectAttributes) {
final RedirectView redirectView = new RedirectView("/book/addBook", true);
BookDTO savedBook = bookService.addBook(bookDto);
redirectAttributes.addFlashAttribute("savedBook", savedBook);
redirectAttributes.addFlashAttribute("addBookSuccess", true);
return redirectView;
}
}
主要方法
@SpringBootApplication(scanBasePackages = "spring.jsp")
@EntityScan("spring.jsp")
@ComponentScan({ "spring.jsp" })
public class JspApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(JspApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(JspApplication.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>
<!-- <packaging>war</packaging> -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>spring</groupId>
<artifactId>jsp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jsp</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-web</artifactId>
</dependency>
<!-- specifies the Tomcat JSP dependency(jsp parser) -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSTL tag lib -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<!-- running in a Tomcat web container. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.4.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.8.4</version>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<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>