1. @RestController注解
SpringMVC提供,在类上加上该注解,表示该类所有接口返回的结果都是为JSON格式。相当于在该类中的接口上都加上了@ResponseBody注解,如果不加该注解,接口默认返回页面跳转。
2.整合静态资源访问
@RequestMapping("/freemarkerIndex")
public String index(Map<String, Object> result) {
result.put("name", "yushengjun");
result.put("sex", "0");
List<String> listResult = new ArrayList<String>();
listResult.add("zhangsan");
listResult.add("lisi");
listResult.add("mayikt");
result.put("listResult", listResult);
return "index";
}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title>首页</title>
</head>
<body>
${name}
<#if sex=="1">
男
<#elseif sex=="2">
女
<#else>
其他
</#if>
<#list userlist as user>
${user}
</#list>
</body>
</html>
1 用符号代替: > gt , >= gte ,< lt , <= lte
2 加括号 <#if(x>y)>
3.使用myThymeleaf渲染Web页面。
视图文件为html格式。
controller:
package com.lzx.controller;
import com.lzx.entity.UserEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author 梁志雄
* @Goal Mercedes-Benz C260
* @date 2023/8/17 17:18
*/
@Controller
public class MyThymeleafController {
@RequestMapping("/myThymeleaf")
public String myThymeleaf(HttpServletRequest request, Map<String,Object> result){ //Http这个是原生的。
//request.setAttribute("user",new UserEntity("lzx",22));
result.put("user",new UserEntity("lzx",22));
return "myThymeleaf";
}
}
html文件:
<!DOCTYPE html>
<!--需要在HTML文件中加入以下语句: -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Show User</title>
</head>
<body>
<table>
姓名:<span th:text="${user.userName}"></span>
年龄:<span th:text="${user.getAge()}"></span>
</table>
</body>
</html>
需要引入该jar包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
加上list和if:
<!DOCTYPE html>
<!--需要在HTML文件中加入以下语句: -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Show User</title>
</head>
<body>
<table>
姓名:<span th:text="${user1.userName}"></span>
年龄:<span th:text="${user1.getAge()}"></span>
<ul th:each="user:${users}">
<li th:text="${user.userName}"></li>
<li th:text="${user.age}"></li>
<span th:if="${user.age>17}">已经成年了</span>
<span th:if="${user.age<17}">未成年</span>
</ul>
</table>
</body>
</html>
4.SpringBoot整合JdbcTemplates
引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
在application.yml配置文件中配置
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
使用JdbcTemplate类来操作数据库:
package com.lzx.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author 梁志雄
* @Goal Mercedes-Benz C260
* @date 2023/8/18 14:21
*/
@RestController
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
@RequestMapping("/insertUser/{userName}/{age}")
public String insertUser(@PathVariable(name = "userName") String userName, @PathVariable(name = "age") Integer age) {
//String insertSql = "INSERT INTO `mayiktmeite`.`users` (`id`, `name`, `age`) VALUES (null, ?, ?);";
//PreparedStatement preparedStatement = new com.mysql.jdbc.PreparedStatement((MySQLConnection) jdbcTemplate,insertSql);
int update = jdbcTemplate.update("INSERT INTO `mayiktmeite`.`users` (`id`, `name`, `age`) VALUES (null, ?, ?);", userName, age);
System.out.println(update);
return update>0?"success":"fail";
}
}
访问接口后,成功实现
5.SpringBoot整合Mybatis框架查询和新增:
需要先引入包:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
在application.yml文件中配置数据源:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mayiktmeite?serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
编写接口:
@RequestMapping("/mybatisFindById")
public UserEntity mybatisFindById(Integer id){
return userMapper.selectByUserId(id);
}
@RequestMapping("/mybatisInsertUser")
public String MybatisInsertUser(String name,Integer age){ //传递的参数可自动接收过来
int insert = userMapper.insertUser(name, age);
return insert>0?"success":"fail";
}
使用?传参形式,也可整合多数据源
datasource:
###会员数据库
member:
jdbc-url: jdbc:mysql://localhost:3306/user
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
###订单数据库
order:
jdbc-url: jdbc:mysql://localhost:3306/order
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
如果是SpringBoot2配置多数据源 ,报如下错误:
“jdbcUrl is required with driverClassName.”或者Cause: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.] with root cause
解决方案:
spring.datasource.url 和spring.datasource.driverClassName,换成
spring.datasource.jdbc-url和spring.datasource.driver-class-name
6. SpringBoot整合热部署框架
devtools:当修改模板文件或Java源代码或者Html文件时,可以在不用重启服务器来加载。通过类加载器ClassLoader来实现的。只适合于本地开发环境。
引入依赖后开启设置完成。
7.引入Lombok插件后,可使用@Data注解让类自动将setter和getter加入到该类的.class文件中去。
在SpringBoot项目中
@Slf4j //该注解为log打印信息集成
8.SpringBoot整合配置文件
yml文件格式比较简洁。
如何读取yml配置文件?使用@Value注解,Spring提供的
在SpringBoot项目中,使用application前缀名文件或者bootstrap都可以
区别:
bootstrap.yml 和 application.yml 都可以用来配置参数。
bootstrap.yml 用来程序引导时执行,应用于更加早期配置信息读取。可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。一旦bootStrap.yml 被加载,则内容不会被覆盖。
application.yml 可以用来定义应用级别的, 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
分布式配置中心:bootstrap.yml
Properties在线转换yml格式网址:https://www.toyaml.com/index.html
9.@Value注解
在application.yml文件中,可以使用@Value("${mayikt.name}") 注解来获取到该文件中的值。
在类的成员属性上加上该注解即可。
10.@ConfigurationProperties注解
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "mayikt")
public class MayiktUserEntity {
private String addres;
private String age;
private String name;
public String getAddres() {
return addres;
}
public String getAge() {
return age;
}
public String getName() {
return name;
}
public void setAddres(String addres) {
this.addres = addres;
}
public void setAge(String age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MayiktUserEntity{" +
"addres='" + addres + '\'' +
", age='" + age + '\'' +
", name='" + name + '\'' +
'}';
}
}
配置文件信息:
mayikt:
addres: www.lzx.com
age: 22
name: mayikt
在控制类中:
@Autowired
private MayiktUserEntity mayiktUserEntity;
@RequestMapping("/getNameAndAgeAddres")
public String getNameAndAgeAddres() {
return mayiktUserEntity.toString();
}
11. 配置文件占位符
在SpringBoot的配置文件中,我们可以使用SpringBoot提供的的一些随机数
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}
-${app.name:默认值} 来制定找不到属性时的默认值
12.多环境配置
在application.yml配置文件中
spring:
profiles:
active: prd
application-dev.yml:开发环境
application-test.yml:测试环境
application-prd.yml:生产环境
13.核心配置
server:
port: 8081
servlet:
context-path: /mayikt
SpringBoot默认的情况下整合Tomcat容器
14. 使用logback记录日志使用logback记录日志
Springboot 已经默认整合好了logback
日志输出文件在当前项目路径log文件夹下
maven依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
logback配置文件:
<configuration>
<!--本文主要输出日志为控制台日志,系统日志,sql日志,异常日志-->
<!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,,,, -->
<!--控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %p (%file:%line\)- %m%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--系统info级别日志-->
<!--<File> 日志目录,没有会自动创建-->
<!--<rollingPolicy>日志策略,每天简历一个日志文件,或者当天日志文件超过64MB时-->
<!--encoder 日志编码及输出格式-->
<appender name="fileLog"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/file/fileLog.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/file/fileLog.log.%d.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 64 MB -->
<maxFileSize>64 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<charset>UTF-8</charset>
<!-- 此处设置字符集 -->
</encoder>
</appender>
<!--sql日志-->
<appender name="sqlFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/sql/sqlFile.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/sql/sqlFile.log.%d.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 64 MB -->
<maxFileSize>64 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。-->
<encoder>
<!--用来设置日志的输入格式-->
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<charset>UTF-8</charset>
<!-- 此处设置字符集 -->
</encoder>
</appender>
<!--异常日志-->
<appender name="errorFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/error/errorFile.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/error/errorFile.%d.log.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 64 MB -->
<maxFileSize>64 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!--对记录事件进行格式化。负责两件事,一是把日志信息转换成字节数组,二是把字节数组写入到输出流。-->
<encoder>
<!--用来设置日志的输入格式-->
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<charset>UTF-8</charset>
<!-- 此处设置字符集 -->
</encoder>
<!--
日志都在这里 过滤出 error
使用 try {}catch (Exception e){} 的话异常无法写入日志,可以在catch里用logger.error()方法手动写入日志
-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志输出级别 -->
<!--All\DEBUG\INFO\WARN\ERROR\FATAL\OFF-->
<!--打印info级别日志,分别在控制台,fileLog,errorFile输出
异常日志在上面由过滤器过滤出ERROR日志打印
-->
<root level="INFO">
<appender-ref ref="fileLog" />
<appender-ref ref="console" />
<appender-ref ref="errorFile" />
</root>
<!--打印sql至sqlFile文件日志-->
<logger name="com.dolphin.mapper" level="DEBUG" additivity="false">
<appender-ref ref="console" />
<appender-ref ref="sqlFile" />
</logger>
</configuration>
在application.yml配置文件中设置:
###指定读取logback配置文件
logging:
config: classpath:log/logback.xml
并在控制类上加上该注解@Slf4j,即可使用log.info()输出日志信息。
日志级别:
1. ALL 最低等级的,用于打开所有日志记录。
2. TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。
3. DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
4. INFO 消息在粗粒度级别上突出强调应用程序的运行过程。打印一些感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
5. WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示
6. ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
7. FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别可以直接停止程序了。
8. OFF 最高等级的,用于关闭所有日志记录。
15. 使用log4j记录日志
日志级别
机制:如果一条日志信息的级别大于等于配置文件的级别,就记录。
trace:追踪,就是程序推进一下,可以写个trace输出
debug:调试,一般作为最低级别,trace基本不用。
info:输出重要的信息,使用较多
warn:警告,有些信息不是错误信息,但也要给程序员一些提示。
error:错误信息。用的也很多。
fatal:致命错误。
输出源
CONSOLE(输出到控制台)
FILE(输出到文件)
格式
SimpleLayout:以简单的形式显示
HTMLLayout:以HTML表格显示
PatternLayout:自定义形式显示
log4j.properties:
#log4j.rootLogger=CONSOLE,info,error,DEBUG
log4j.rootLogger=DEBUG,error,CONSOLE,info
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.logger.info=info
log4j.appender.info=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.info.datePattern='.'yyyy-MM-dd
log4j.appender.info.Threshold = info
log4j.appender.info.append=true
log4j.appender.info.File=E:/code/log/info.log
log4j.logger.error=error
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.error.datePattern='.'yyyy-MM-dd
log4j.appender.error.Threshold = error
log4j.appender.error.append=true
log4j.appender.error.File=E:/code/log/error.log
log4j.logger.DEBUG=DEBUG
log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
log4j.appender.DEBUG.datePattern='.'yyyy-MM-dd
log4j.appender.DEBUG.Threshold = DEBUG
log4j.appender.DEBUG.append=true
log4j.appender.DEBUG.File=E:/code/log/dubug.log
maven依赖:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- spring boot start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<!-- 排除自带的logback依赖 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springboot-log4j -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
指定路径:
###指定log4j.properties配置文件路径
logging:
config: classpath:log4j.properties
16. 使用AOP统一处理Web请求日志
基于AOP实现 或者elk
在接口的前后实现拦截 减少打印日志代码的冗余性的问题
maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
AOP切面相关配置类:
@Aspect
@Component
public class WebLogAspect {
private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.lzx.controller.*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 记录下请求内容
logger.info("URL : " + request.getRequestURL().toString());
logger.info("HTTP_METHOD : " + request.getMethod());
logger.info("IP : " + request.getRemoteAddr());
Enumeration<String> enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String name = (String) enu.nextElement();
logger.info("name:{},value:{}", name, request.getParameter(name));
}
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("RESPONSE : " + ret);
}
}
17. 使用@Scheduled注解创建定时任务
在Spring Boot的主类中App加入@EnableScheduling注解,启用定时任务的配置
@Component
public class ScheduledTasks {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}
}
注解里面的参数,可以在
quartz/Cron/Crontab表达式在线生成工具-BeJSON.com
该网址来进行可视化转换
大型企业一般使用Xxl-job
18. 使用@Async实现异步调用
启动类加上@EnableAsync ,需要执行异步方法上加入@Async
@Async实际就是多线程封装的
异步线程执行方法有可能会非常消耗cpu的资源,所以大的项目建议使用
Mq异步实现。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 每秒需要多少个线程处理?
* tasks/(1/taskcost)
*/
private int corePoolSize = 3;
/**
* 线程池维护线程的最大数量
* (max(tasks)- queueCapacity)/(1/taskcost)
*/
private int maxPoolSize = 3;
/**
* 缓存队列
* (coreSizePool/taskcost)*responsetime
*/
private int queueCapacity = 10;
/**
* 允许的空闲时间
* 默认为60
*/
private int keepAlive = 100;
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(corePoolSize);
// 设置最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 设置队列容量
executor.setQueueCapacity(queueCapacity);
// 设置允许的空闲时间(秒)
//executor.setKeepAliveSeconds(keepAlive);
// 设置默认线程名称
executor.setThreadNamePrefix("thread-");
// 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}
需要异步的代码块:
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @ClassName MemberServiceAsync
* @Author 蚂蚁课堂余胜军 QQ644064779 www.mayikt.com
* @Version V1.0
**/
@Slf4j
@Component
public class MemberServiceAsync {
@Async("taskExecutor")
public String smsAsync() {
log.info(">02<");
try {
log.info(">正在发送短信..<");
Thread.sleep(3000);
} catch (Exception e) {
}
log.info(">03<");
return "短信发送完成!";
}
}
注意:如果异步注解写当前自己类,有可能aop会失效,无法拦截注解,最终导致异步注解失效,需要经过代理类调用接口;
所以需要将异步的代码单独抽取成一个类调用接口。
19.全局捕获异常
@ExceptionHandler 表示拦截异常
- @ControllerAdvice 是 controller 的一个辅助类,最常用的就是作为全局异常处理的切面类
- @ControllerAdvice 可以指定扫描范围
- @ControllerAdvice 约定了几种可行的返回值,如果是直接返回 model 类的话,需要使用 @ResponseBody 进行 json 转换
- 返回 String,表示跳到某个 view
- 返回 modelAndView
- 返回 model + @ResponseBody
@ControllerAdvice
public class MayiktExceptionHandler {
/**
* 拦截运行异常出现的错误~~~
*
* @return
*/
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public Map<Object, Object> exceptionHandler() {
Map<Object, Object> map = new HashMap<>();
map.put("error", "500");
map.put("msg", "系统出现错误~");
return map;
}
}
20. 发布打包
在命令行中
使用mvn package 打包
使用java –jar 包名
如果报错信息为没有主清单,在pom文件中新增
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.mayikt.App</mainClass>
<excludes>
<exclude>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclude>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>