这里写目录标题
- springboot后台搭建
- 1. 创建父项目
- 1.1 创建netseal
- 2. 创建子项目
- 2.1 创建webserver
- 2.2 创建common
- 3.正式编码
- 3.1 修改pom文件
- 3.1.1 netseal的pom.xml
- 3.1.2 webserver的pom.xml
- 3.1.3 common的pom.xml
- 3.2 填充子项目
- 3.2.1 数据源配置
- 3.2.2 引入本地jar
- 3.3 全局统一异常处理
- 3.4 文件上传
- 3.4.1 base64
- 3.4.2 MultipartResolver
- 4. Q&A
- 4.1 Test failures
- 4.2 启动项目无法注入common的dao
- 5. 打包及运行
- 跨域问题
springboot后台搭建
本次搭建使用多模块的方式,建立一个父项目netseal,父项目下建立webserver、common、appserver等项目。
- 父项目——netseal,maven项目即可
- 子项目——webserver,springboot项目
- 子项目——common,springboot项目
idea进行项目的创建可参考使用idea搭建springboot项目
1. 创建父项目
1.1 创建netseal
填写group和artifact。
2. 创建子项目
2.1 创建webserver
填写group和artifact。
初始化选择spring web即可。模块分离后,web端只需要spring web,数据库相关的由其他模块引入。
2.2 创建common
初始化选择spring web、jdbc、mysql等。此次项目是模块化的测试,故继续沿用jdbc,暂未整合mybatis。
3.正式编码
3.1 修改pom文件
3.1.1 netseal的pom.xml
- 重点1:打包方式为pom
- 重点2:引入子模块
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.com.infosec</groupId>
<artifactId>netseal</artifactId>
<version>1.0-SNAPSHOT</version>
<!--重点1:打包方式为pom-->
<packaging>pom</packaging>
<!--重点2:引入子模块-->
<modules>
<module>webserver</module>
<module>common</module>
</modules>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
3.1.2 webserver的pom.xml
- 重点1:填写父项目的基本信息,relativePath值为…/pom.xml
- 重点2:打包方式为jar
- 重点3:依赖common
- 重点4:打包配置
- 重点5:关掉单元测试
<?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>
<!--重点1:填写父项目的基本信息-->
<parent>
<groupId>cn.com.infosec</groupId>
<artifactId>netseal</artifactId>
<version>1.0-SNAPSHOT</version>
<!--子级Maven的pom文件中,relativePath标签使用的默认值:“<relativePath/>”,但编译环境(IDEA和命令行)不认这种写法
应使用<relativePath>../pom.xml</relativePath>
-->
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>cn.com.infosec.netseal</groupId>
<artifactId>webserver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>webserver</name>
<!--重点2:打包方式为jar-->
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--内部引用-->
<!--重点3:依赖common-->
<dependency>
<groupId>cn.com.infosec.netseal</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--外部引用-->
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<!--重点4:打包,使用maven的插件进行打包时:可指定主类的类路径、并把依赖的包打进jar-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--指定主类-->
<mainClass>cn.com.infosec.netseal.webserver.WebserverApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!--重点5:关掉单元测试,否则项目无法正常启动-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
3.1.3 common的pom.xml
- 重点1:填写父项目的基本信息
- 重点2:打包方式为jar
<?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>
<!--重点1:填写父项目的基本信息-->
<parent>
<groupId>cn.com.infosec</groupId>
<artifactId>netseal</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>cn.com.infosec.netseal</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common</name>
<!--重点2:打包方式为jar-->
<packaging>jar</packaging>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
3.2 填充子项目
webserver和common进行建包、添加文件等操作。
webserver:包含controller、service等;
common:包含entity、dao等;
3.2.1 数据源配置
common的application.yml
指定serverTimezone=UTC,不指定可能会报错
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/netseal_4_data?&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
username: root
password: root
3.2.2 引入本地jar
不可避免的,在公司开发项目,会使用到公司自己的jar,所以此时就不能从仓库中获取。
方法:在项目下建立lib资源目录,存放自己的jar。
pom.xml
添加完依赖,可以在项目上选择Maven——Reimport。
<!--本地jar-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>configuration2</artifactId>
<version>2.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-configuration2-2.1.jar</systemPath>
</dependency>
3.3 全局统一异常处理
Springboot对于异常的处理也做了不错的支持,它提供了一个 @ControllerAdvice(@RestControllerAdvice)注解以及 @ExceptionHandler注解,前者是用来开启全局的异常捕获,后者则是说明捕获哪些异常,对那些异常进行处理。
/**
* 全局异常处理器
*
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(WebDataException.class)
public Object WebDataException(WebDataException e) {
String message = e.getMessage();
return R.error(message);// R是响应类,在此处统一响应错误状态码及信息
}
@ExceptionHandler(Exception.class)
public R handleException(Exception e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
}
3.4 文件上传
对于文件,我们可以采用两种方式:
- base64:前台获取文件的base64,后台解码就能得到文件;
- MultipartResolver:大文件使用传统方式上传;
3.4.1 base64
3.4.2 MultipartResolver
通常情况下,我们使用上传时,是需要将表单信息和文件一起提交给后台的。
前端
通常前端和后台的交互采用json格式。
使用new FormData()封装文件和其他信息,提交的时候大概是自动由json格式转为了文件上传表单的形式。
后端
后台的方法收到的数据就不是json,就不能再用@RequestBody注解来接收参数了。
springboot关于MultipartResolver有个坑,内置的MultipartResolver有点问题,我们可以用下述方式解决;
- 显性注册MultipartResolver
package cn.com.infosec.netseal.webserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Configuration
public class UploadConfig {
//显示声明CommonsMultipartResolver为mutipartResolver
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
//resolveLazily属性启用是为了推迟文件解析,以在在UploadAction中捕获文件大小异常
resolver.setResolveLazily(true);
resolver.setMaxInMemorySize(40960);
//上传文件大小 5M 5*1024*1024
resolver.setMaxUploadSize(5 * 1024 * 1024);
return resolver;
}
}
- 启动类排除内置MultipartResolver
如果不排除内置MultipartResolver,显性注册的MultipartResolver会无效。
@SpringBootApplication(exclude = {MultipartAutoConfiguration.class})
public class WebServerApplication {
public static void main(String[] args) {
SpringApplication.run(WebServerApplication.class, args);
}
}
4. Q&A
4.1 Test failures
Q:
Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project webserver: There are test failures.
- A:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
4.2 启动项目无法注入common的dao
Q:
启动webserver的WebserverApplication方法,会发现common的dao无法被自动注入,报错如下:
Field sysUserDao in cn.com.infosec.netseal.webserver.service.sysUser.SysUserServiceImpl required a bean of type 'cn.com.infosec.netseal.common.dao.sysUser.SysUserDaoImpl' that could not be found.
- A:
解决办法:
在WebserverApplication上使用@ComponentScan(“cn.com.infosec.netseal”)
package cn.com.infosec.netseal.webserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("cn.com.infosec.netseal")
public class WebserverApplication {
public static void main(String[] args) {
SpringApplication.run(WebserverApplication.class, args);
}
}
5. 打包及运行
因为主类在webserver,所以打包写在了webserver下的pom.xml,但是操作是点击父项目的package!!!成功会看到控制台输出build success,jar包生成在了webserver下的target目录。
webserver启动:
父项目打包:
将webserver-0.0.1-SNAPSHOT.jar复制到其他磁盘下,打开命令窗口,进入该路径,执行
java -jar xxx.jar即可运行。
java -jar xxx.jar
示例:
跨域问题
package cn.com.infosec.netseal.webserver.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Filter配置
*
* @author lhx
*/
@Configuration
public class FilterConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口
.allowCredentials(true) // 是否发送 Cookie
.allowedOriginPatterns("*") // 支持域
.allowedMethods("GET", "POST", "PUT", "DELETE") // 支持方法
.allowedHeaders("*")
.exposedHeaders("*");
}
}