SpringBoot - 集成Swagger2、Knife4j接口文档/升级版swagger-bootstrap-ui配置以及账号密码登录

SpringBoot - 集成Swagger2、Knife4j接口文档/升级版swagger-bootstrap-ui配置以及账号密码登录

pom引入

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>1.9.6</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--原生swagger ui-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

配置类SwaggerConfig

package your.package.config;

import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
        		.apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("your.package.controller"))
                .paths(PathSelectors.any())
                .build();
    }
    
    /**
     * API 说明,包含作者、简介、版本、host、服务URL
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("XXXAPI文档")
                .description("XXXAPI文档")
                //.contact(new Contact("API文档", "http://www.XXX.com/", "xxx@qq.com"))//作者信息
                //.version("1.0")//定义api 版本号
                .build();
    }
}

请注意@Configuration和@EnableSwagger2注解。这两个注解分别表示这是一个配置类,以及启用了Swagger 2。只有在这两个注解都存在的情况下,Swagger才会被正确启用。

如果您的项目使用的是Swagger 3(即OpenAPI 3),则配置文件可能如下所示:

package your.package.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
@EnableOpenApi
public class SwaggerConfig {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .select()
                .apis(RequestHandlerSelectors.basePackage("your.package.controller"))
                .paths(PathSelectors.any())
                .build();
    }
}

访问http://localhost:8080/swagger-ui.html(假设项目运行在8080端口)应该可以看到Swagger UI。如果您的项目使用的是OpenAPI 3,访问http://localhost:8080/swagger-ui/index.html

启动项目

访问http://localhost:8080/swagger-ui.html
在这里插入图片描述
访问http://localhost:8080/doc.html
在这里插入图片描述

账号密码登录

现有需求,/swagger-ui.html 页面需要添加登录认证,但是本来的接口不需要登录认证

一、使用http://localhost:8080/swagger-ui.html路径访问,设置账号密码登录:

为Swagger UI添加登录权限,我使用Spring Security来实现。首先,确保您已经在项目中添加了Spring Security依赖。在pom.xml文件中添加以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

从application.yml文件中读取用户名和密码

# 自定义swagger登录拦截,拦截路径swagger-ui.html和/doc.html
custom-swagger-security:
  basic:
    enabled: false
    path: /swagger-ui.html
  user:
    name: admin #账号
    password: 123456  #密码

接下来,创建一个配置类来配置Spring Security。在src/main/java/your/package/config目录下,创建一个名为SecurityConfig.java的文件,并添加以下内容:

package your.package.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${security.user.name}")
    private String username;

    @Value("${security.user.password}")
    private String password;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/swagger-ui.html").authenticated()
                //.antMatchers(HttpMethod.GET, "/webjars/**", "/swagger-resources/**", "/v2/api-docs").permitAll()
                .anyRequest().permitAll()
            .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser(username)
                .password("{noop}" + password)
                .roles("USER");
    }
}

这个配置类继承了WebSecurityConfigurerAdapter,并覆盖了configure(HttpSecurity http)和configure(AuthenticationManagerBuilder auth)方法。在configure(HttpSecurity http)方法中,我们配置了对/swagger-ui.html的访问需要认证,同时允许访问其他必要的资源。

在configure(AuthenticationManagerBuilder auth)方法中,我们设置了一个内存中的用户(admin)和密码(123456)。这里我们使用了明文密码,但在实际生产环境中,请确保使用加密的密码。

在Spring Security 5中,可以使用"{noop}"前缀来表示不对密码进行加密。这将告诉Spring Security使用NoOpPasswordEncoder来处理密码。将此前缀添加到SecurityConfig.java中的.password()方法中,可以解决 "There is no PasswordEncoder mapped for the id 'null'" 错误。

请注意,这种方法不建议在生产环境中使用,因为它不安全。在生产环境中,您应该使用一个安全的密码编码器,例如 BCryptPasswordEncoder。

现在,当您访问http://localhost:8080/swagger-ui.html时,浏览器会要求您输入用户名和密码。只有在输入正确的用户名和密码后,您才能访问Swagger UI。
在这里插入图片描述

二、使用http://localhost:8080/doc.html路径访问,设置账号密码登录:

knife4j相比swagger-ui更加强大,针对Swagger的资源接口,Knife4j提供了简单的Basic认证功能,个人觉得文档页面样式也更加简洁明了
1、yml中添加配置

knife4j:
  # 开启增强配置 
  enable: true
  # 开启生产环境屏蔽,配置此属性为true,所有资源都会屏蔽输出.
  production: false
 # 开启Swagger的Basic认证功能,默认是false
  basic:
      enable: true
      # Basic认证用户名
      username: admin
      # Basic认证密码
      password: 123456

2、在swagger-ui基础上只是多了@EnableSwaggerBootstrapUi类注解

@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUi
public class SwaggerConfig implements WebMvcConfigurer {
	
}

访问效果:
在这里插入图片描述

注意

knife4j:
  # 开启增强配置 
  enable: true
 # 开启生产环境屏蔽
  production: true

配置此属性后,所有资源都会屏蔽输出.

效果图如下:
在这里插入图片描述

调整

由于http://localhost:8080/swagger-ui.htm和http://localhost:8080/doc.htm都需要登录配置。
为了做统一权限验证,所以此处实现方法如下:
1、yml中配置如下

# 自定义swagger登录拦截,拦截路径swagger-ui.html和/doc.html
custom-swagger-security:
  basic:
    enabled: false
    path: /swagger-ui.html
  user:
    name: admin #账号
    password: 123456  #密码

修改

package your.package.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Security配置拦截
 * 1、开启swagger-ui.html原生页面认证
 * @author chenp
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${custom-swagger-security.basic.enabled:false}")
    private boolean basicEnabled;

    @Value("${custom-swagger-security.basic.path}")
    private String basicPath;

    @Value("${custom-swagger-security.user.name}")
    private String username;

    @Value("${custom-swagger-security.user.password}")
    private String password;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable(); // Disable CSRF protection for simplicity

        if (basicEnabled) {
            http.authorizeRequests()
                    // swagger页面需要添加登录校验
                    .antMatchers(HttpMethod.GET, "/swagger-ui.html", "/doc.html").authenticated() // Require authentication for Swagger UI
                    //其他请求全部允许
                    .anyRequest().permitAll() // Allow all other requests
                    .and()
                    .httpBasic(); // Enable basic authentication
        } else {
            http.authorizeRequests()
                    .anyRequest().permitAll();
        }
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser(username)
                // Use clear text password for simplicity, but don't use it in production
                //.password("{noop}" + password)
                //{noop}是使用明文密码,不进行加密,不建议使用在生产环境,在生产环境中,使用一个安全的密码编码器,例如 BCryptPasswordEncoder
                .password(passwordEncoder().encode(password))
                .roles("USER");
    }
}

ps:此处对{noop}密码编码器改为使用一个安全的密码编码器,例如 BCryptPasswordEncoder

加强版swagger-bootstrap-ui配置

swagger-bootstrap-ui相比swagger-ui更加强大,提供测试及账号密码验证登录等配置,个人觉得文档页面样式更加简洁明了
配置方式基本与swagger-ui一致
1、pom依赖

<!--swagger-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>swagger-bootstrap-ui</artifactId>
    <version>1.9.6</version>
</dependency>

2、添加配置类SwaggerConfig:在swagger-ui基础上只是多了@EnableSwaggerBootstrapUI类注解

import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.XXX.web.controller"))//扫描包范围
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * API 说明,包含作者、简介、版本、host、服务URL
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("XXXAPI文档")
                .description("XXXAPI文档")
                //.contact(new Contact("API文档", "http://www.XXX.com/", "xxx@qq.com"))//作者信息
                //.version("1.0")//定义api 版本号
                .build();
    }
}

:如果有登录验证等拦截器,如下资源需要放行

@Component
public class MyInterceptorConfigure extends WebMvcConfigurationSupport { //WebMvcConfigurer

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // excludePathPatterns 用户排除拦截
        String[] excludePathPatterns = { "/swagger-ui.html/**","/swagger-resources/**","/webjars/**","/v2/**"};
		registry.addInterceptor(userTokenInterceptor).addPathPatterns("/**").excludePathPatterns(excludePathPatterns);
        super.addInterceptors(registry);
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
  }

3:yml配置文件添加接口文档访问自定义账号密码

#配置swagger登陆验证
swagger:
  production: false
  basic:
    enable: true
    username: admin
    password: 123456

4、修改拦截器等放行资源
主要修改:

String[] excludePathPatterns = { "/doc.html/**","/swagger-resources/**","/webjars/**","/v2/**"};
@Component
public class MyInterceptorConfigure extends WebMvcConfigurationSupport { //WebMvcConfigurer

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // excludePathPatterns 用户排除拦截
        String[] excludePathPatterns = { "/doc.html/**","/swagger-resources/**","/webjars/**","/v2/**"};
		registry.addInterceptor(userTokenInterceptor).addPathPatterns("/**").excludePathPatterns(excludePathPatterns);
        super.addInterceptors(registry);
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
  }

访问地址

localhost:8080/doc.html

资源参考
https://doc.xiaominfo.com/docs/features/accesscontrol
swagger配置及升级版swagger-bootstrap-ui配置+访问账号密码登录限制
直接使用security.basic.path无效|——springboot2.0以上的security的配置
SpringBoot - 集成Swagger、Knif4j接口文档以及文档添加账号密码登录
Swagger设置密码登录
Spring Boot整合Swagger3.0及Knife4j

默 唁
关注 关注
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot 整合 swagger2 配置账号密码登录 demo代码
闲走天涯的博客
08-05 7495
一、pom文件引入swagger依赖 <!-- swagger2-restful接口测试 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version>
Knife4j各版本集成SpringBoot 2.x 3.x版本demo示例
04-23
在本示例中,我们将探讨如何将Knife4j集成Spring Boot 2.x和3.x版本中,以实现高效且美观的API文档生成。 首先,让我们了解Knife4j的基本概念。Knife4j是由xiaoymin开发的,它是Swagger UI的一个增强版,提供了更...
swagger配置升级版swagger-bootstrap-ui配置+访问账号密码登录限制
weixin_43568232的博客
10-21 7471
本文主要介绍swagger-ui及加强版swagger-bootstrap-ui配置 一:普通swagger-ui配置 1:pom添加依赖 <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId>
SpringBoot 集成 Swagger-Bootstrap-UI
zhzjn的博客
08-07 600
后来觉得它不太好用,在浏览技术网站的时候,偶然发现swagger-bootstrap-ui,于是便重构了,把swagger-bootstrap-ui整合进来,后来发现不仅仅对我们后端有帮助,主要方便我们将接口进行归类,同样对安卓小伙伴也有帮助,他们可以看这个接口文档进行联调。当初我使用swagger-boostrap-ui的时候,那个时候还是1.x版本,如今swagger-bootsrap-ui到2.x,同时也更改名字knife4j,适用场景从过去的单体到微服务。代码语言:javascript。
swagger-bootstrap-ui 配置
qq_27865749的博客
03-10 498
springboot 配置swagger maven 依赖 <!--swagger-api 依赖开始--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</
swagger-bootstrap-ui配置
m0_59663619的博客
08-22 399
swagger-bootstrap-ui配置
基于Java的knife4jswagger-bootstrap-ui集成框架示例项目设计源码
04-11
本源码提供了一个基于Java的knife4jswagger-bootstrap-ui集成框架示例项目设计。项目包含1445个文件,其中包括1110个Java源文件、71个XML文件、46个Gitignore文件、45个YAML文件、37个Markdown文档、30个JSON文件...
113-springboot-demo-knife4j-v2.rar
03-07
本质是Swagger的增强解决方案,前身只是一个SwaggerUIswagger-bootstrap-uiKnife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案, 前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,...
113-springboot-demo-knife4j-v3.rar
03-07
本质是Swagger的增强解决方案,前身只是一个SwaggerUIswagger-bootstrap-uiKnife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案, 前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,...
swagger-bootstrap-uiSwagger-bootstrap-uiSwagger的前端UI实现,目的是替换Swagger的默认UI实现Swagger-UI,使文档更加友好...
02-25
swagger-bootstrap-ui 该项目在GitHub上停止更新,最新代码可在gitee上获取,网址为 另请在上提及新的PR和问题 英文介绍| 介绍 Swagger-bootstrap-UIspringfox-swagger的增强型UI实现,它使Java开发人员在使用...
springboot 项目集成swagger配置请求头 swagger-bootstrap-ui配置访问密码
weixin_44076260的博客
01-15 3446
目录 1.什么是 swagger?优势有哪些 2.springboot 集成 swagger 2.1.引入 swagger 相关的jar包 2.2.编写配置文件 SwaggerConfig WebConfiguration(有配置请求头) 2.3.访问 swagger 2.4.异常及解决办法 2.5.最后的效果是这个样子的 3.springboot 集成 swagger-bootstrap-ui 3.1.引入jar包 3.2.修改配置 3.3.最后效果 3.4.swagge...
SpringBoot SwaggerUi 进行登录访问,配置用户名,密码
一起记录GIS学习
03-25 1万+
添加成功入下图所示: 在pom中引入jar <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 然后在yml文件中进行配置spring: security: basic: path: /
SpringBoot swagger 配置账号密码
热门推荐
赵先森
09-18 4万+
生产环境下springbootswagger 配置账号密码 &amp;amp;lt;!-- 鉴权 --&amp;amp;gt; &amp;amp;lt;dependency&amp;amp;gt; &amp;amp;lt;groupId&amp;amp;gt;org.springframework.boot&amp;amp;lt;/groupId&amp;amp;gt;
swagger添加访问密码
zlfjavahome的专栏
06-28 4954
swagger添加访问密码
Swagger-Bootstrap-UI
世上哪有什么岁月静好,不过是有人替你负重前行
07-09 3755
UI增强包主要包括两大核心功能:文档说明 和 在线调试文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,使用swagger-bootstrap-ui能根据该文档说明,对该接口的使用情况一目了然。
SpringBoot - 集成Swagger、Knif4j接口文档以及文档添加账号密码登录
weixin_39651356的博客
11-28 3466
集成Swagger、Knif4j接口文档以及文档添加账号密码登录
swagger增强 knife4j-spring-boot-starter启动器,开启密码访问
qq_40319804的博客
08-19 2657
swagger文档开启用户名密码
Swagger-Bootstrap-UIKnife4j)使用教程
最新发布
gitblog_00835的博客
09-14 407
Swagger-Bootstrap-UIKnife4j)使用教程 swagger-bootstrap-ui Knife4j is a set of Swagger2 and OpenAPI3 All-in-one enhancement solution ...
knife4j-openapi2-spring-boot-starter
08-19
knife4j-openapi2-spring-boot-starter 是一个用于集成 Knife4j(原 Swagger-Bootstrap-UI)的 Spring Boot Starter。Knife4j 是一个基于 Swagger 的 API 文档生成和展示工具,它提供了一套简洁美观的界面,方便...
写文章

热门文章

  • mybatis-plus使用sum,count,distinct等函数的方法 17600
  • 【Windows上同时安装两个不同版本MYSQL】MySQL安装教程--5.7和8.0版本 17244
  • IDEA热部署设置(自动/手动 两种方式) 11766
  • springboot 数据源配置出错(Failed to configure a DataSource: ‘url‘ attribute is not specified and no ......) 10510
  • Mybatis:解决xml属性报红色及眼花缭乱的黄色警告 5608

分类专栏

  • JAVA 12篇
  • MySQL 3篇
  • VUE 12篇
  • JS 4篇
  • css 2篇

最新评论

  • 【Windows上同时安装两个不同版本MYSQL】MySQL安装教程--5.7和8.0版本

    不哭的猫: 5.7的安装也是和8.0一样吗 我直接安装不了5.7的

  • 【Windows上同时安装两个不同版本MYSQL】MySQL安装教程--5.7和8.0版本

    TODO_LIST: 那你选择一下数据库不就行了

  • 【Windows上同时安装两个不同版本MYSQL】MySQL安装教程--5.7和8.0版本

    Enlaipersistent: 显示no database selected

  • 【Windows上同时安装两个不同版本MYSQL】MySQL安装教程--5.7和8.0版本

    Enlaipersistent: 第八步5.7版本修改密码整不起啊,作者,求帮助

  • 使用MySQL的INSERT INTO ... ON DUPLICATE KEY UPDATE进行高效数据插入和更新

    CSDN-Ada助手: MySQL入门 技能树或许可以帮到你:https://edu.csdn.net/skill/mysql?utm_source=AI_act_mysql

大家在看

  • 【快速上手】linux环境下Neo4j的安装与使用
  • 黑神话:悟空 后话 189
  • 简单生活的快乐 337

最新文章

  • 使用MySQL的INSERT INTO ... ON DUPLICATE KEY UPDATE进行高效数据插入和更新
  • easypoi动态设置列宽,解决自动设置列宽失效
  • POI 导出Excel 并且根据内容设置列宽自适应
2024年4篇
2023年13篇
2022年4篇
2021年12篇
2020年9篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家主题玻璃钢卡通雕塑手工制作怀化商场美陈孟津玻璃钢雕塑价格大型主题商场美陈采购南明区玻璃钢雕塑制作电话温州耐高温玻璃钢花盆河南太湖石玻璃钢景观雕塑设计铜川玻璃钢雕塑厂家批发安全的玻璃钢花盆山东艺术商场美陈供应苏州玻璃钢人物雕塑批发石膏线玻璃钢雕塑宁夏抽象人物玻璃钢雕塑云浮玻璃钢雕塑批发老人玻璃钢雕塑工艺玻璃钢雕塑生产无锡玻璃钢雕塑工程绍兴玻璃钢海豚雕塑价格河南节庆商场美陈哪家好美陈商场动物雕塑透明玻璃钢雕塑工厂莆田园林玻璃钢雕塑哪家好兰州仿真玻璃钢雕塑定制玻璃钢拐杖糖雕塑定西城市玻璃钢雕塑定制玻璃钢大树雕塑安装辽源观音玻璃钢雕塑定做商丘玻璃钢雕塑设计花盆曲阳哪里有玻璃钢雕塑厂家辉县玻璃钢雕塑设计香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化