Closed
Description
Describe the bug
- If you are reporting a bug, please help to speed up problem diagnosis by providing as
much information as possible: - A clear and concise description of what the bug is: the title of an issue is not enough
To Reproduce
Steps to reproduce the behavior:
- creat project
-
use OpenAPI
-
code
-
run
-
get erro
- What version of spring-boot you are using?
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
- What modules and versions of springdoc-openapi are you using?
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-data-rest -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-data-rest</artifactId>
<version>1.6.14</version>
</dependency>
- What is the actual and the expected result using OpenAPI Description (yml or json)?
data:
rest:
base-path: /api/rest
-
Provide with a sample code (HelloController) or Test that reproduces the problem
response status is 500 /v3/api-docs/JLYShop-public
Expected behavior -
A clear and concise description of what you expected to happen.
-
What is the expected result using OpenAPI Description (yml or json)?
/**
* 根据商品名称模糊查询指定日期前的商品信息
*
* @param name 商品名称
* @param end 指定日期结束
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
@Parameter(name = "商品名称", required = true) String name,
@Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Dec 18 00:14:20 CST 2022
There was an unexpected error (type=Internal Server Error, status=500).
Cannot invoke "org.springframework.data.repository.query.Param.value()" because the return value of "java.lang.reflect.Parameter.getAnnotation(java.lang.Class)" is null
java.lang.NullPointerException: Cannot invoke "org.springframework.data.repository.query.Param.value()" because the return value of "java.lang.reflect.Parameter.getAnnotation(java.lang.Class)" is null
at org.springdoc.data.rest.core.DataRestOperationService.getParameterType(DataRestOperationService.java:241)
at org.springdoc.data.rest.core.DataRestOperationService.buildSearchOperation(DataRestOperationService.java:208)
at org.springdoc.data.rest.core.DataRestOperationService.buildOperation(DataRestOperationService.java:135)
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperation(DataRestRouterOperationService.java:287)
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperation(DataRestRouterOperationService.java:226)
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildRouterOperationList(DataRestRouterOperationService.java:192)
at org.springdoc.data.rest.core.DataRestRouterOperationService.buildSearchRouterOperationList(DataRestRouterOperationService.java:147)
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.lambda$findSearchControllers$13(SpringRepositoryRestResourceProvider.java:383)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
at java.base/java.util.HashMap$ValueSpliterator.forEachRemaining(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchControllers(SpringRepositoryRestResourceProvider.java:383)
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.findSearchResourceMappings(SpringRepositoryRestResourceProvider.java:362)
at org.springdoc.data.rest.SpringRepositoryRestResourceProvider.getRouterOperations(SpringRepositoryRestResourceProvider.java:276)
at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$1(OpenApiResource.java:169)
at java.base/java.util.Optional.ifPresent(Unknown Source)
at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$2(OpenApiResource.java:168)
at java.base/java.util.Optional.ifPresent(Unknown Source)
at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:164)
at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:364)
at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:139)
at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:116)
at org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource.openapiJson(MultipleOpenApiWebMvcResource.java:88)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:769)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Unknown Source)
Screenshots
If applicable, add screenshots to help explain your problem.
This can work:
This work not very good:
Additional context
Add any other context about the problem here.
- entity
@Data
@MappedSuperclass
@DynamicInsert(true)
@DynamicUpdate(true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public abstract class BaseEntity implements Serializable {
/** SVUDI */
private static final long serialVersionUID = 1L;
/** 数据库中的ID */
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID", unique = true, nullable = false, insertable = false, updatable = false)
private Long id;
...
/**
* 数据是否合法
*
* @return 是否合法
*/
public abstract boolean isValid();
}
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "PRODUCT_ENTITY")
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class ProductEntity extends BaseEntity implements Comparable<ProductEntity> {
/** SVUDI */
private static final long serialVersionUID = 1L;
/** 名字. */
@NotNull
@Column(nullable = false)
private String name;
/** 单价. */
@NotNull
@Column(nullable = false)
private BigDecimal price;
/** 分类 */
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CATEGORY_ID")
private ProductCategoryEntity category;
/** 日期. */
@NotNull
@Column(nullable = false)
private LocalDate date;
@Override
public boolean isValid() {
return name != null && price != null && date != null;
}
/** 根据日期排序 */
@Override
public int compareTo(ProductEntity oProduct) {
return this.getDate().compareTo(oProduct.getDate());
}
}
- Swagger3Config
@Configuration
public class Swagger3Config {
@Bean
GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("JLYShop-public")
.pathsToMatch("/api/**")
.build();
}
@Bean
OpenAPI jlyShopOpenApi() {
return new OpenAPI()
.info(new Info()
.title("JLYShop API")
.description("Spring shop sample application")
.version("v0.0.1")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("SpringDoc Wiki Documentation")
.url("https://springdoc.org/v2"));
}
}
/**
* 商品信息
*
* @author zctmdc
*/
@RepositoryRestResource(path = "product")
public interface ProductRepository extends JpaRepository<ProductEntity, Long> {
/**
* 根据商品名称查询商品信息
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByName(@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称查询最新的商品信息
*
* @param name 商品名称
* @return 商品信息
*/
ProductEntity findTopByNameOrderByDateDesc(@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称模糊查询商品信息并按时间降序排序
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCaseOrderByDateDesc(
@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称模糊查询商品信息并按时间降序排序
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCase(
@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称模糊查询指定日期前的商品信息
*
* @param end 指定日期结束
* @return 商品信息列表
*/
List<ProductEntity> findByDateBefore(
@Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
/**
* 根据商品名称模糊查询指定日期前的商品信息
*
* @param name 商品名称
* @param end 指定日期结束
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
@Parameter(name = "商品名称", required = true) String name,
@Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
/**
* 查询分类是null的商品信息
*
* @return 商品信息列表
*/
List<ProductEntity> findByCategoryIsNull();
}
ProductRepository
@RepositoryRestResource(path = "product")
public interface ProductRepository extends JpaRepository<ProductEntity, Long> {
/**
* 根据商品名称查询商品信息
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByName(@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称查询最新的商品信息
*
* @param name 商品名称
* @return 商品信息
*/
ProductEntity findTopByNameOrderByDateDesc(@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称模糊查询商品信息并按时间降序排序
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCaseOrderByDateDesc(
@Parameter(name = "商品名称", required = true) String name);
/**
* 根据商品名称模糊查询商品信息
*
* @param name 商品名称
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCase(
@Parameter(name = "商品名称", required = true) String name);
/**
* 查询指定日期前的商品信息
*
* @param end 指定日期结束
* @return 商品信息列表
*/
List<ProductEntity> findByDateBefore(
@Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
/**
* 根据商品名称模糊查询指定日期前的商品信息
*
* @param name 商品名称
* @param end 指定日期结束
* @return 商品信息列表
*/
List<ProductEntity> findByNameContainingIgnoreCaseAndDateBefore(
@Parameter(name = "商品名称", required = true) String name,
@Parameter(name = "区间结束日期", required = true) @DateTimeFormat(pattern = DATE_PATTERN) @Param("end") LocalDate end);
/**
* 查询分类是null的商品信息
*
* @return 商品信息列表
*/
List<ProductEntity> findByCategoryIsNull();
}
- 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.6</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>cn.xx</groupId>
<artifactId>shop</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shop</name>
<description>Demo project for HJAJLY SHop</description>
<properties>
<java.version>17</java.version>
<version.fastjson2>2.0.8</version.fastjson2>
<version.jfiglet>0.0.9</version.jfiglet>
<version.easyexcel>3.1.1</version.easyexcel>
<version.sqlite>3.39.2.0</version.sqlite>
</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.data</groupId>
<artifactId>spring-data-rest-hal-explorer</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>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</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>
<!-- javax.validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${version.fastjson2}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.lalyos/jfiglet -->
<dependency>
<groupId>com.github.lalyos</groupId>
<artifactId>jfiglet</artifactId>
<version>${version.jfiglet}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${version.easyexcel}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>${version.sqlite}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-data-rest -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-data-rest</artifactId>
<version>1.6.14</version>
</dependency>
</dependencies>
<build>
<finalName>shop</finalName>
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>