这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spring-boot-modules/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<module>spring-boot-3-url-matching</module>
<module>spring-boot-graalvm-docker</module>
<module>spring-boot-validations</module>
<module>spring-boot-openapi</module>
</modules>

<dependencyManagement>
Expand Down
96 changes: 96 additions & 0 deletions spring-boot-modules/spring-boot-openapi/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?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>
<artifactId>spring-boot-openapi</artifactId>
<name>spring-boot-openapi</name>
<packaging>jar</packaging>
<description>OpenAPI Generator module</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/>
</parent>


<!-- <parent>-->
<!-- <groupId>com.baeldung.spring-boot-modules</groupId>-->
<!-- <artifactId>spring-boot-modules</artifactId>-->
<!-- <version>1.0.0-SNAPSHOT</version>-->
<!-- </parent>-->

<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<skipValidateSpec>true</skipValidateSpec>
<inputSpec>${project.basedir}/src/main/resources/api/quotes.yaml</inputSpec>
<generatorName>spring</generatorName>
<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
<templateResourcePath>${project.basedir}/src/main/resources/templates/JavaSpring</templateResourcePath>
<globalProperties>
<debugOpenAPI>true</debugOpenAPI>
</globalProperties>
<configOptions>
<dateLibrary>java8</dateLibrary>
<openApiNullable>false</openApiNullable>
<delegatePattern>true</delegatePattern>
<apiPackage>com.baeldung.tutorials.openapi.quotes.api</apiPackage>
<modelPackage>com.baeldung.tutorials.openapi.quotes.api.model</modelPackage>
<documentationProvider>source</documentationProvider>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<openapi-generator.version>7.3.0</openapi-generator.version>
<swagger-annotations.version>2.2.20</swagger-annotations.version>
</properties>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.baeldung.tutorials.openapi.quotes;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

import com.baeldung.tutorials.openapi.quotes.service.BrokerService;

@SpringBootApplication
@EnableCaching
public class QuotesApplication {

public static void main(String[] args) {
SpringApplication.run(QuotesApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.baeldung.tutorials.openapi.quotes.config;

import java.time.Clock;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ClockConfiguration {

@Bean
@ConditionalOnMissingBean
Clock defaultClock() {
return Clock.systemDefaultZone();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.baeldung.tutorials.openapi.quotes.controller;

import java.time.Clock;
import java.time.OffsetDateTime;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import com.baeldung.tutorials.openapi.quotes.api.QuotesApi;
import com.baeldung.tutorials.openapi.quotes.api.QuotesApiDelegate;
import com.baeldung.tutorials.openapi.quotes.api.model.QuoteResponse;
import com.baeldung.tutorials.openapi.quotes.service.BrokerService;

@Component
public class QuotesApiImpl implements QuotesApiDelegate {
private final BrokerService broker;
private final Clock clock;

public QuotesApiImpl(BrokerService broker, Clock clock) {
this.broker = broker;
this.clock = clock;
}


/**
* GET /quotes/{symbol} : Get current quote for a security
*
* @param symbol Security&#39;s symbol (required)
* @return OK (status code 200)
* @see QuotesApi#getQuote
*/
@Override
public ResponseEntity<QuoteResponse> getQuote(String symbol) {

var price = broker.getSecurityPrice(symbol);

var quote = new QuoteResponse();
quote.setSymbol(symbol);
quote.setPrice(price);
quote.setTimestamp(OffsetDateTime.now(clock));
return ResponseEntity.ok(quote);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.baeldung.tutorials.openapi.quotes.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

@Service
public class BrokerService {

private final Logger log = LoggerFactory.getLogger(BrokerService.class);

private final Random rnd = new Random();


public BrokerService() {
}


public BigDecimal getSecurityPrice(@NonNull String symbol) {
log.info("getSecurityPrice: {}", symbol);
// Just a mock value
return BigDecimal.valueOf(100.0 + rnd.nextDouble()*100.0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
openapi: 3.0.0
info:
title: Quotes API
version: 1.0.0
servers:
- description: Test server
url: http://localhost:8080
paths:
/quotes/{symbol}:
get:
tags:
- quotes
summary: Get current quote for a security
operationId: getQuote
x-spring-cacheable:
name: get-quotes
security:
- ApiKey:
- Quotes.Read
parameters:
- name: symbol
in: path
required: true
description: Security's symbol
schema:
type: string
pattern: '[A-Z0-9]+'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/QuoteResponse'
components:
securitySchemes:
ApiKey:
type: apiKey
in: header
name: X-API-KEY
schemas:
QuoteResponse:
description: Quote response
type: object
properties:
symbol:
type: string
description: security's symbol
price:
type: number
description: Quote value
timestamp:
type: string
format: date-time
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

logging:
level:
root: INFO
org.springframework: INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Generated code: do not modify !
* Custom template with support for x-spring-cacheable extension
*/
package {{package}};

{{#imports}}import {{import}};
{{/imports}}
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
{{#useResponseEntity}}
import org.springframework.http.ResponseEntity;
{{/useResponseEntity}}
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.multipart.MultipartFile;
{{#reactive}}
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.http.codec.multipart.Part;
{{/reactive}}

{{#useBeanValidation}}
import {{javaxPackage}}.validation.constraints.*;
import {{javaxPackage}}.validation.Valid;
{{/useBeanValidation}}
import java.util.List;
import java.util.Map;
import java.util.Optional;
{{#async}}
import java.util.concurrent.CompletableFuture;
{{/async}}
import {{javaxPackage}}.annotation.Generated;

{{#operations}}
/**
* A delegate to be called by the {@link {{classname}}Controller}}.
* Implement this interface with a {@link org.springframework.stereotype.Service} annotated class.
*/
{{>generatedAnnotation}}
public interface {{classname}}Delegate {
{{#jdk8-default-interface}}

default Optional<NativeWebRequest> getRequest() {
return Optional.empty();
}
{{/jdk8-default-interface}}

{{#operation}}
/**
* {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}}
{{#notes}}
* {{.}}
{{/notes}}
*
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return {{#responses}}{{message}} (status code {{code}}){{^-last}}
* or {{/-last}}{{/responses}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
* @see {{classname}}#{{operationId}}
*/
{{#isDeprecated}}
@Deprecated
{{/isDeprecated}}
{{#vendorExtensions.x-spring-cacheable}}
@org.springframework.cache.annotation.Cacheable({{#name}}"{{.}}"{{/name}}{{^name}}"default"{{/name}})
{{/vendorExtensions.x-spring-cacheable}}
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>responseType}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{^isArray}}Mono<{{{dataType}}}>{{/isArray}}{{#isArray}}Flux<{{{baseType}}}>{{/isArray}}{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}{{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}MultipartFile{{/reactive}}{{#isArray}}>{{/isArray}}{{/isFile}} {{paramName}}{{^-last}},
{{/-last}}{{/allParams}}{{#reactive}}{{#hasParams}},
{{/hasParams}}ServerWebExchange exchange{{/reactive}}{{#vendorExtensions.x-spring-paginated}}{{#hasParams}}, {{/hasParams}}{{^hasParams}}{{#reactive}}, {{/reactive}}{{/hasParams}}final Pageable pageable{{/vendorExtensions.x-spring-paginated}}){{#unhandledException}} throws Exception{{/unhandledException}}{{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}} {
{{>methodBody}}
}{{/jdk8-default-interface}}

{{/operation}}
}
{{/operations}}
Loading