SwaggerConfig

main
Vks 3 months ago
parent 94cd912f93
commit dc602f7317

@ -0,0 +1,18 @@
package com.cyberlanting.Assignments.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@Slf4j
public class SwaggerConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("静态资源映射");
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springdoc-openapi-ui/")
.resourceChain(false);
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

@ -0,0 +1,83 @@
<?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.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cyberlanting</groupId>
<artifactId>Assignments</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Assignments</name>
<description>Assignments</description>
<url/>
<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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-compiler-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <annotationProcessorPaths>-->
<!-- <path>-->
<!-- <groupId>org.projectlombok</groupId>-->
<!-- <artifactId>lombok</artifactId>-->
<!-- </path>-->
<!-- </annotationProcessorPaths>-->
<!-- </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>

@ -0,0 +1,13 @@
package com.cyberlanting.Assignments;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AssignmentsApplication {
public static void main(String[] args) {
SpringApplication.run(AssignmentsApplication.class, args);
}
}

@ -0,0 +1,88 @@
package com.cyberlanting.Assignments.controller;
import com.cyberlanting.Assignments.pojo.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Tag(name = "用户模块")
@RestController
@RequestMapping("/users")
public class UserController {
// 创建线程安全的Map模拟users信息的存储
static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
/**
* "/users/"GET
*
* @return
*/
@Operation(summary = "获取用户列表")
@GetMapping("/")
public List<User> getUserList() {
// 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递
List<User> r = new ArrayList<User>(users.values());
return r;
}
/**
* "/users/"POSTUser
*
* @param user
* @return
*/
@Operation(summary = "新建用户")
@PostMapping("/")
public String postUser(@RequestBody User user) {
// @RequestBody注解用来绑定通过http请求中application/json类型上传的数据
users.put(user.getId(), user);
return "success";
}
/**
* "/users/{id}"GETurlidUser
*
* @param id
* @return
*/
@Operation(summary = "根据id获取用户")
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// url中的id可通过@PathVariable绑定到函数的参数中
return users.get(id);
}
/**
* "/users/{id}"PUTUser
*
* @param id
* @param user
* @return
*/
@Operation(summary = "根据id修改用户")
@PutMapping("/{id}")
public String putUser(@PathVariable Long id, @RequestBody User user) {
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return "success";
}
/**
* "/users/{id}"DELETEUser
*
* @param id
* @return
*/
@Operation(summary = "删除用户")
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
users.remove(id);
return "success";
}
}

@ -0,0 +1,12 @@
package com.cyberlanting.Assignments.pojo;
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
}

@ -0,0 +1,11 @@
spring:
application:
name: Assignments
#springdoc:
# api-docs:
# enable: true
# path: /v3/api-docs
# swagger-ui:
# enable: true
# path: /swagger-ui.html

@ -0,0 +1,88 @@
package com.cyberlanting.Assignments;
import com.cyberlanting.Assignments.controller.UserController;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.nio.charset.StandardCharsets;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@SpringBootTest
class AssignmentsApplicationTests {
private MockMvc mvc;
@BeforeEach
public void setUp() {
mvc = MockMvcBuilders.standaloneSetup(new UserController())
.defaultResponseCharacterEncoding(StandardCharsets.UTF_8) // 编码格式
.addDispatcherServletCustomizer(dispatcher ->
dispatcher.setDispatchOptionsRequest(true))
.build();
}
@Test
public void testUserController() throws Exception {
// 测试UserController
RequestBuilder request;
// 1、get查一下user列表应该为空
request = get("/users/");
mvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().string(equalTo("[]")));
// 2、post提交一个user
request = post("/users/")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"id\":1,\"name\":\"测试大师\",\"age\":20}");
mvc.perform(request)
.andExpect(content().string(equalTo("success")));
// 3、get获取user列表应该有刚才插入的数据
request = get("/users/");
mvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().string(equalTo("[{\"id\":1,\"name\":\"测试大师\",\"age\":20}]")));
// 4、put修改id为1的user
request = put("/users/1")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"测试终极大师\",\"age\":30}");
mvc.perform(request)
.andExpect(content().string(equalTo("success")));
// 5、get一个id为1的user
request = get("/users/1");
mvc.perform(request)
.andExpect(content().string(equalTo("{\"id\":1,\"name\":\"测试终极大师\",\"age\":30}")));
// 6、del删除id为1的user
request = delete("/users/1");
mvc.perform(request)
.andExpect(content().string(equalTo("success")));
// 7、get查一下user列表应该为空
request = get("/users/");
mvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().string(equalTo("[]")));
}
}

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="zh - CN">
<head>
<meta charset="UTF - 8">
<meta name="viewport" content="width=device-width, initial - scale=1.0">
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;500;700&display=swap" rel="stylesheet">
<title>风景视图</title>
</head>
<body>
<div class="tab-container">
<div class="tab-nav">
<button class="tab-item active" data-target="content1">标签一</button>
<button class="tab-item" data-target="content2">标签二</button>
<button class="tab-item" data-target="content3">标签三</button>
<button class="tab-item" data-target="content4">标签四</button>
</div>
<div class="tab-content">
<div id="content1" class="content-panel active">
<p>在湖畔的黄昏里,天空与山脉共舞,云霞映照出生命的绚烂。站在码头的尽头,我们都是这宇宙中的微小尘埃,却也能感受到大自然的壮丽与宁静。每一刻的美丽,都是生命对我们的馈赠,让我们学会珍惜,学会欣赏。</p>
<img src="./imgs/1-lakes.jpg" alt="示例图片">
</div>
<div id="content2" class="content-panel">
<p>在这片静谧的自然角落,两只鸟儿相互依偎,彼此间的默契如同它们头顶上那金色的羽冠般闪耀。它们的存在是对抗孤独的力量,也是对和谐共生最美好的诠释。在这个瞬息万变的世界里,唯有真挚的情感才能跨越一切界限,让心灵得以栖息。</p>
<img src="./imgs/2-brown.jpg" alt="示例图片">
</div>
<div id="content3" class="content-panel">
<p>在这幅画面中,火烈鸟们优雅地站立着,它们的羽毛呈现出鲜艳的粉红色调,仿佛是大自然赋予的色彩盛宴。背景是一片翠绿的竹林,与火烈鸟形成了鲜明的对比。阳光透过树叶洒下斑驳的光影,为整个场景增添了一丝神秘的氛围。这两只火烈鸟似乎正在享受彼此的陪伴,它们的姿态亲密而温馨,让人感受到自然界中那份纯真的美好。</p>
<img src="./imgs/3-birds.jpg" alt="示例图片">
</div>
<div id="content4" class="content-panel">
<p>在这片宁静的山谷中,湖水清澈见底,倒映着巍峨的山峰和苍翠的森林。山峰被夕阳染成了金黄色,与蓝天白云相映成趣。这里是大自然的杰作,是人类心灵的净土。在这里,我们可以感受到生命的美好,领悟到人与自然的和谐共生。让我们珍惜这片土地,守护这份宁静,让大自然永远绽放它的光彩。</p>
<img src="./imgs/4-lake-mount.jpg" alt="示例图片">
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@ -0,0 +1,16 @@
document.querySelector('.tab-nav').addEventListener('click', function(e) {
const tabItem = e.target.closest('.tab-item');
if (!tabItem) return;
//全部清除acrive状态
document.querySelectorAll('.tab-item, .content-panel').forEach(el => {
el.classList.remove('active');
});
//标签页active
tabItem.classList.add('active');
//将当前的active状态添加到对应的标签内容中
const targetId = tabItem.dataset.target;
document.getElementById(targetId).classList.add('active');
});

@ -0,0 +1,50 @@
.tab-container {
max-width: 800px;
margin: 20px auto;
}
.tab-nav {
display: flex;
border-bottom: 2px solid #eee;
}
.tab-item {
padding: 12px 24px;
background: none;
border: none;
cursor: pointer;
transition: all 0.3s;
}
.tab-item.active {
border-bottom: 3px solid #2196F3;
color: #2196F3;
}
.content-panel {
display: none;
padding: 20px;
animation: fadeIn 0.5s;
}
.content-panel.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.content-panel{
width: 80%;
height: 80%;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
body .tab-item{
font-family: 'Noto Sans SC', sans-serif;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Loading…
Cancel
Save