• [Spring Boot 6]企业级开发


    本节内容主要就几个常用的模块进行解读,在众多企业级开发中常常用得到
    例如邮件发送这一功能其实非常常见,在一般的网站设计中会有对注册邮件的激活功能,此时就需要用到这个功能了,一般来说激活邮件需要设置UUID 来进行验证,如果用户点击了链接那么在数据库的状态就转换为1,表示已经激活了。
    定时任务也用得比较多,常见于缓存进入数据库等,可以看我这篇关于高并发的章节 高并发Demo
    这里讲的批处理主要是针对批量导入数据库的快捷方法(这样就不用进入excel一行一行导入了)
    目前很多项目也是需要讲究前后端分离的,所以一个好的接口测试是非常有必要的,之前我们使用了Postman 来进行测试,不过依旧缺少点详细信息,这里使用Swagger2 来进行测试,不过值得一提的是,以前老的配置方法非常坑,我也是花了相当的时间才找到了一个合适的办法。

    希望对你有所帮助!

    邮件发送

    邮件发送是非常常见的功能,注册时的身份验证、重要通知发送都会用到邮件发送。Sun公司提供了JavaMail,但是配置相当繁琐,Spring 提供了JavaMailSender来简化,Spring Boot则提供了MailSenderAutoConfiguration对邮件做了进一步简化。

    发送前的准备

    这里以QQ邮箱发送邮件为例:需要开通POP3/SMTP服务或者IMAP/SMTP服务。SMTP就是简单邮件传输协议,定义了邮件客户端和SMTP服务器之间、以及SMTP与SMTP之间的通信规则。也就是说aaa@qq.com 用户先将邮件投递给腾讯的SMTP,然后邮件投递到网易的SMTP服务器,此时SMTP服务器就是用来接收邮件的。POP3 邮局协议,定义了客户端与POP3 服务器之间的规则。

    在这里插入图片描述

    这样你就会得到一个授权码了。

    发送

    添加邮件依赖:

    	<dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-mailartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    项目创建成功后,在application.properties 完成邮件基本信息配置:

    spring.mail.host=smtp.qq.com
    spring.mail.port=465
    spring.mail.username = 1739994163@qq.com
    spring.mail.password=授权码
    spring.mail.default-encoding=utf-8
    spring.mail.properties.mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
    spring.mail.properties.mail.debug=true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里配置了邮件服务器的地址、端口(可以是465或者587)、用户账号和密码以及默认编码、SSL连接配置,最后开启debug,这样方便开发者查看邮件发送日志。注意,SSL的配置可以在QQ邮箱官方文档查看

    发送一个简单的邮件,创建一个MailService用来封装邮件的发送:

    @Component
    public class MailService {
        @Resource
    // 在MailSenderPropertiesConfiguration类配置好的,该类在Mail 自动配置类导入,
    // 只要注入就可以了
        JavaMailSender javaMailSender;
        public void sendSimpleMail(String from, String to, String cc, String subject, String content) {
    // 5个参数,分别是邮件发送者,收件人,抄送人,邮件主题,邮件内容      
    	SimpleMailMessage simpMsg = new SimpleMailMessage();
            simpMsg.setFrom(from);
            simpMsg.setTo(to);
            simpMsg.setCc(cc);
            simpMsg.setSubject(subject);
            simpMsg.setText(content);
            javaMailSender.send(simpMsg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    配置完成后,可以在单元测试中写一个测试方法进行测试:

    import com.example.testspringboot.service.MailService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.Context;
    
    import javax.annotation.Resource;
    import java.io.File;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    
    
    public class SendmailApplicationTests {
    
        @Resource
        MailService mailService;
        @Test
        public void sendSimpleMail() {
            mailService.sendSimpleMail("1739994163@qq.com",
                    "qazjou@163.com",
                    "1739994163@qq.com",
                    "测试邮件主题",
                    "测试邮件内容");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    执行该方法,便可以看到邮件发送成功了:

    在这里插入图片描述

    发送带附件的邮件:
    通过调用Attachment 方法即可添加附件,该方法调用多个方法添加附件,在MailService添加:

     public void sendAttachFileMail(String from, String to,
                                       String subject, String content, File file) {
            try {
                MimeMessage message = javaMailSender.createMimeMessage();
                MimeMessageHelper helper = new MimeMessageHelper(message,true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content);
                helper.addAttachment(file.getName(), file);
                javaMailSender.send(message);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用了MimeMessageHelper简化了配置,构造方法的第二个参数true 表示构造一个multipart message 类型的邮件,此类型的邮件包含了多个正文、附件等,最后在单元测试进行测试:

     @Test
        public void sendAttachFileMail() {
            mailService.sendAttachFileMail("1739994163@qq.com",
                    "qazjou@163.com",
                    "测试邮件主题",
                    "测试邮件内容",
                    new File("C:\\Users\\17399\\Desktop\\1.txt"));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    运行后可见发送成功了。

    在这里插入图片描述

    有的邮件正文可能要插入图片,此时就不是附件的内容了,使用FileSystemResource实现功能:

    public void sendMailWithImg(String from, String to,
                                    String subject, String content,
                                    String[] srcPath,String[] resIds) {
            if (srcPath.length != resIds.length) {
                System.out.println("发送失败");
                return;
            }
            try {
                MimeMessage message = javaMailSender.createMimeMessage();
                MimeMessageHelper helper =
                        new MimeMessageHelper(message,true);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content,true);
                for (int i = 0; i < srcPath.length; i++) {
                    FileSystemResource res =
                            new FileSystemResource(new File(srcPath[i]));
                    helper.addInline(resIds[i], res);
                }
                javaMailSender.send(message);
            } catch (MessagingException e) {
                System.out.println("发送失败");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在发送邮件时候分别传入图片资源路径和资源id,构造静态资源,然后调用addInline方法将资源加入邮件对象中。注意,在调用setText方法时候,第二个参数true 表示邮件正文是HTML格式的,该参数默认为false。

    @Test
        public void sendMailWithImg() {
            mailService.sendMailWithImg("1739994163@qq.com",
                    "qazjou@163.com",
                    "测试邮件主题(图片)",
                    "
    hello,这是一封带图片资源的邮件:" + "这是图片1:
    "
    + "这是图片2:
    "
    + "
    "
    , new String[]{"C:\\Users\\17399\\Desktop\\2.png", "C:\\Users\\17399\\Desktop\\3.png"}, new String[]{"p01", "p02"}); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果如图:

    在这里插入图片描述

    定时任务

    @Scheduled

    定时任务是企业开发最常见的功能之一,如定时统计订单数、数据库备份、定时发送短信和邮件、定时统计博客访客。简单的定时任务直接通过@Scheduled 注解来实现,复杂的定时任务集成Quartz来实现。关于Quartz 可以看我这篇博客,Quartz任务

    <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    开启定时任务:
    在项目启动类添加注解开启定时任务:

    @EnableScheduling
    @SpringBootApplication
    
    • 1
    • 2

    定时任务主要 @Component 来进行配置:

    @Component
    public class MySchedule {
    // 来标注一个定时任务,其中fixedDelay=1000 表示在当前任务结束后1s开始另一个任务
    // initialDelay=1000 表示首次执行的延迟时间
        @Scheduled(fixedDelay = 1000)
        public void fixedDelay() {
            System.out.println("fixedDelay:"+new Date());
        }
        @Scheduled(fixedRate = 2000)
        public void fixedRate() {
            System.out.println("fixedRate:"+new Date());
        }
        @Scheduled(initialDelay = 1000,fixedRate = 2000)
        public void initialDelay() {
            System.out.println("initialDelay:"+new Date());
        }
    // 也可以使用cron 表达式,来表示任务每分钟执行一次
        @Scheduled(cron = "0 * * * * ?")
        public void cron() {
            System.out.println("cron:"+new Date());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    配置完成后启动项目即可,定时任务部分打印日志如下:
    在这里插入图片描述

    Quartz

    是一个功能丰富的开源作业调度库,由Java写成,可以集成在任何Java程序中,使用Quartz可以创建简单或者复杂的执行任务,支持数据库、集群、插件等,并且支持cron 表达式,有很高的灵活性,Spring Boot集成Quartz和Spring 集成非常类似,主要提供三个Bean: JobDetail,Trigger以及SchedulerFactory.

    创建依赖:

    <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-quartzartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    然后创建两个Job:
    MyFirstJob.java:

    import org.springframework.stereotype.Component;
    
    import java.util.Date;
    
    @Component
    public class MyFirstJob {
        public void sayHello() {
            System.out.println("MyFirstJob:sayHello:"+new Date());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    MySecondJob.java:

    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.springframework.scheduling.quartz.QuartzJobBean;
    
    import java.util.Date;
    
    public class MySecondJob extends QuartzJobBean {
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        @Override
        protected void executeInternal(JobExecutionContext context){
            System.out.println("hello:"+name+":"+new Date());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Job可以一个普通的JavaBean,如果是普通的JavaBean,那么可以添加@Component注解将之注册到Spring 容器中。当然也可以使用继承抽象类QuartzJobBean,则需要实现该类的executeInternal 方法,在任务被调用时候使用。接下来创建对JobDetail和Trigger 进行配置:

    @Configuration
    public class QuartzConfig {
    // 两种方法配置JobDetail,只需要指定Job的实例名和要调用的方法即可,
    // 注册这种方法无法在创建JobDetail 传递参数
        @Bean
        MethodInvokingJobDetailFactoryBean jobDetail1() {
            MethodInvokingJobDetailFactoryBean bean =
                    new MethodInvokingJobDetailFactoryBean();
            bean.setTargetBeanName("myFirstJob");
            bean.setTargetMethod("sayHello");
            return bean;
        }
    // 指定JobClass 即可,通过JobDtaMap 传递参数到Job中,Job只需要提供属性名和set
        @Bean
        JobDetailFactoryBean jobDetail2() {
            JobDetailFactoryBean bean = new JobDetailFactoryBean();
            bean.setJobClass(MySecondJob.class);
            JobDataMap jobDataMap = new JobDataMap();
            jobDataMap.put("name","sang");
            bean.setJobDataMap(jobDataMap);
            bean.setDurability(true);
            return bean;
        }
    // Trigger 有不同的实现方法,这里展示常用的Trigger:
    // 这里设置JobDetail ,通过setRepeatCount 配置任务循环次数
        @Bean
        SimpleTriggerFactoryBean simpleTrigger() {
            SimpleTriggerFactoryBean bean =
                    new SimpleTriggerFactoryBean();
            bean.setJobDetail(jobDetail1().getObject());
            bean.setRepeatCount(3);
    // 启动延迟时间
            bean.setStartDelay(1000);
    // 任务时间间隔
            bean.setRepeatInterval(2000);
            return bean;
        }
    // 主要配置JobDetail 和Cron 表达式
        @Bean
        CronTriggerFactoryBean cronTrigger() {
            CronTriggerFactoryBean bean =
                    new CronTriggerFactoryBean();
            bean.setJobDetail(jobDetail2().getObject());
            bean.setCronExpression("* * * * * ?");
            return bean;
        }
        @Bean
        SchedulerFactoryBean schedulerFactory() {
            SchedulerFactoryBean bean = new SchedulerFactoryBean();
            SimpleTrigger simpleTrigger = simpleTrigger().getObject();
            CronTrigger cronTrigger = cronTrigger().getObject();
            bean.setTriggers(simpleTrigger,cronTrigger);
            return bean;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    配置完成后,便可以启动项目了,此时需要将前面在启动类的注解删去:

    在这里插入图片描述

    批处理

    Spring Batch 是一个开源的、全面的、轻量级的批处理框架,通过给此可以实现强大的批处理应用程序的开发。Spring Batch 提供了记录/追踪,事务管理,作业处理统计等,可以结合定时任务发挥更大的作用。
    也提供了ItemReader、ItemProcessor和Item Writer 来完成数据的读取,可将执行状态持久化到数据库中。下面通过简单的数据复制展示Spring Batch。

    创建依赖以及数据库相关依赖:

    <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-batchartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4

    添加数据库依赖是为了将批处理的执行状态持久化到数据库中,配置相应的信息:

    spring.datasource.type= com.alibaba.druid.pool.DruidDataSource
    #spring.datasource.url=jdbc:mysql:///ay_user
    #spring.datasource.url=jdbc:mysql:///jpa
    spring.datasource.url = jdbc:mysql:///ay_user
    spring.datasource.username= root
    spring.datasource.password=q1
    # 表示项目启动时候创建数据表的SQL 脚本位置(由batch提供)
    spring.datasource.schema = classpath:/org/springframework/batch/core/schema-mysql.sql
    #  表示在项目启动时执行建表SQL
    spring.batch.jdbc.initialize-schema=always
    # 不自动执行,需要用户手动触发执行
    spring.batch.job.enabled=false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    接着在项目启动类上添加注解:

    @EnableBatchProcessing
    @SpringBootApplication
    
    • 1
    • 2

    然后配置批处理:

    @Configuration
    public class CsvBatchJobConfig {
    // 注入三个对象进行备用,这里持久化的方案是JDBC
        @Resource
        JobBuilderFactory jobBuilderFactory;
        @Resource
        StepBuilderFactory stepBuilderFactory;
        @Resource
        DataSource dataSource;
    // 配置ItemReader,Batch 提供了常用的ItemReader
        @Bean
        @StepScope
        FlatFileItemReader<MUser> itemReader() {
    // 加载一个普通文件的ItemReader
            FlatFileItemReader<MUser> reader = new FlatFileItemReader<>();
    // 第一行是标题所以要跳过
            reader.setLinesToSkip(1);
    // 找到配置的位置,此时已经写了,放在classpath目录下了
            reader.setResource(new ClassPathResource("data.csv"));
    // 设置每一行的信息
            reader.setLineMapper(new DefaultLineMapper<MUser>(){{
                setLineTokenizer(new DelimitedLineTokenizer(){{
                    setNames("id","username","address","gender");
    // 配置列与列之间的间隔符
                    setDelimiter("\t");
                }});
    // 设置要映射的实体属性
                setFieldSetMapper(new BeanWrapperFieldSetMapper<MUser>(){{
                    setTargetType(MUser.class);
                }});
            }});
            return reader;
        }
    // 数据的写出逻辑
        @Bean
        JdbcBatchItemWriter jdbcBatchItemWriter() {
            JdbcBatchItemWriter writer = new JdbcBatchItemWriter();
            writer.setDataSource(dataSource);
    // 注意占位符的写法: :属性名
            writer.setSql("insert into muser(id,username,address,gender) " +
                    "values(:id,:username,:address,:gender)");
            writer.setItemSqlParameterSourceProvider(
                    new BeanPropertyItemSqlParameterSourceProvider<>());
            return writer;
        }
    // 配置一个Step,通过get来获取一个StepBuilder
        @Bean
        Step csvStep() {
            return stepBuilderFactory.get("csvStep")
                    .<MUser, MUser>chunk(2)
                    .reader(itemReader())
                    .writer(jdbcBatchItemWriter())
                    .build();
        }
        @Bean
        Job csvJob() {
            return jobBuilderFactory.get("csvJob")
                    .start(csvStep())
                    .build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    这里涉及了一个MUser实体类:

    public class MUser {
        private Integer id;
        private String username;
        private String address;
        private String gender;
    // 省略set 和get 方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    此时在classpath 下的data.csv文件如下:
    在这里插入图片描述

    现在创建一个Controller ,当用户发起请求时候触发批处理:

    注意此时jobLauncher.run括号的第二个参数不要写出null 否则会报错,直接生成new对象即可。

    @RestController
    public class BatchController {
        @Resource
        JobLauncher jobLauncher;
        @Resource
        Job job;
    
        @GetMapping("/testbatch")
        public String batchtest() {
            try{
    // 框架提供,job是刚刚配置的,调用run方法来批处理
                jobLauncher.run(job,new JobParameters());
            }catch (Exception e) {
                e.printStackTrace();
            }
            return "success";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    最后运行以后,会在batch库中创建多个批处理相关的库,这些表是用来记录批处理的执行状态,此时data.csv数据成功插入user 表。:
    在这里插入图片描述

    此时查看数据,已经成功插入表中:
    在这里插入图片描述

    Swagger 2

    前后端分离开发中,为了减少沟通成本,一般需要构建RESTful API 文档来描述所有的接口信息,但仍有一些弊端,说明:

    1. 接口众多,编写RESTful API 文档工作量大,因为要包含接口的基本信息,例如接口地址、接口请求参数、接口返回值等。
    2. 维护不方便,一旦接口发生了变化,需要修改文档
    3. 接口测试不方便,只能借助于第三方工具,例如Postman来测试。

    Swagger 2是一个开源软件框架,可以帮助开发人进行设计、构建、记录和使用等,将代码和文档融为一体,可以完美解决上述问题,可以较好地集中在业务当中,同时也可以非常好整合在Spring Boot.

    用常规的依赖太老了,不兼容我2.7版本的Spring Boot。

    # 这个依赖更好,可以Swagger 2的兼容(可以比较方便的做升级了)
    <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-boot-starterartifactId>
            <version>3.0.0version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建Swagger2 的配置类:

    还有一种办法就是可以在启动类上面,加@EnableOpenApi 就直接可以运行了。(这个方法非常简单)

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig  implements WebMvcConfigurer {
        @Bean
    // Docket is a builder which is intended to be the primary interface into the swagger-springmvc framework. 
        Docket docket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.testspringboot.controller"))
                    .paths(PathSelectors.any()) // 所有包
                    .build().apiInfo(new ApiInfoBuilder()
                            .description("接口文档")
                            .contact(new Contact("Jacin","baidu.com","1@qq.com"))
                            .version("v1.0")
                            .title("测试文档")
                            .license("Apache")
                            .licenseUrl("apache.org")
                            .build());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    通过@EnableSwagge2 注解开启 Swagger 2 ,主要是配置一个Docket,通过apis方法配置要扫描的controller 位置,通过paths 方法配置路径。在apiInfo 构建文档的基本信息,例如描述、联系人信息、版本等。
    Swagger 2配置完成后,接下来开发接口了:

    @RestController
    //用来描述整个Controller 信息,默认就是类名
    @Api(tags="用户接口")
    public class SwaggerController {
    // 用在方法上,描述一个信息,value 是简单的描述,notes 用来备注方法的详细作用
        @ApiOperation(value = "查询用户",notes = "根据id")
    // 方法上,描述方法的参数
    // paramType 是方法参数的类型,可选值有path( PathVariable),query(@RequestParam)
    // name 表示参数名称,和下面的参数变量对应
    //  value 是参数描述信息,required 吧iOS是否必填   
     @ApiImplicitParam(paramType = "path",name="id",value = "用户id",required = true)
        @GetMapping("/user/{id}")
        public String getUserById(@PathVariable Integer id) {
            return "/user/"+ id;
        }
    // 这个是响应结果的描述,code 是响应码,message是描述信息,有多个那么就放在一个里面
        @ApiResponses({
                @ApiResponse(code = 200,message = "删除成功"),
                @ApiResponse(code = 500,message = "删除失败")
        })
        @ApiOperation(value = "删除用户",notes = "id删除")
        @DeleteMapping("/user/{id}")
        public Integer deletUserById(@PathVariable Integer id) {
            return  id;
        }
    
        @ApiOperation(value = "添加用户",notes = "添加一个用户,传入用户名和地址")
        @ApiImplicitParams({
                @ApiImplicitParam (paramType = "query" ,name = "username",value = "用户名",required = true,defaultValue = "sang"),
                @ApiImplicitParam(paramType = "query" ,name = "address",value = "用户地址",required = true,defaultValue = "sang")
        })
        @PostMapping("/user")
        public String addUser(@RequestParam String username,@RequestParam String address) {
            return username + ":" + address;
        }
        @ApiOperation(value = "修改用户",notes = "修改用户,传入用户信息")
    //    @PostMapping("/user")
    //    public String updateUser(@RequestBody MUser user) {
    //        return user.toString();
    //    }
        @GetMapping("/ignore")
    // 不对某个接口生成文档
        @ApiIgnore
        public void ingoreMethod() {
    
        }
    
        @GetMapping("tst")
        public String tst() {
            return "tst";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    此时输入:http://localhost:8081/swagger-ui/index.html# (注意新版的格式

    这次更新,移除了原来默认的swagger页面路径:http://host/context-path/swagger-ui.html,新增了两个可访问路径:http://host/context-path/swagger-ui/index.html和http://host/context-path/swagger-ui/
    在这里插入图片描述

    不过我一开始使用的是依赖是 (以下方法不一定成功)

     <dependency>
                <groupId>io.springfoxgroupId>
                <artifactId>springfox-swagger2artifactId>
                <version>3.0.0version>
            dependency>
            <dependency>
                <groupId>io.springfoxgroupId>
                <artifactId>springfox-swagger-uiartifactId>
                <version>3.0.0version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    而且用的http://localhost:8081/swagger-ui/ 发现怎么都进不去,一直报error.
    查看swagger-ui 位置:
    在这里插入图片描述

    此时构造一个Webconfig 来实现 WebMvcConfigurer 接口方法:

        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            // 解决静态资源⽆法访问
            registry.addResourceHandler("/**")
                    .addResourceLocations("classpath:/static/");
            // 解决swagger⽆法访问
            registry.addResourceHandler("/swagger-ui.html")
                    .addResourceLocations("classpath:/META-INF/resources/");
            // 解决swagger的js⽂件⽆法访问
            registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    不过我这里确实没实现出来,应该是spring boot 版本问题。毕竟swagger2 太久没更新了,所以使用新版的swagger2。

    以上。

  • 相关阅读:
    【图论C++】树的直径(DFS 与 DP动态规划)
    ThinkPHP5文档——路由
    spring使用websocket 的两种方式
    java泛型机制详解篇二(深入理解泛型篇一)
    【STM32】文件系统FATFS与Flash的初步使用
    R语言修改dataframe数据列的名称:使用dplyr包的rename函数修改列名、使用colnmaes函数修改列名、在数据筛选的时候重命名列名
    SpringMVC 框架详解
    树莓派通过frp实现内网穿透打通ssh[操作记录]
    基于springboot,vue图书管理系统
    基于fast-Unet的补强胶胶体在线识别分割技术
  • 原文地址:https://blog.csdn.net/QAZJOU/article/details/128191742