目录
1.父子类工程创建及聚合工程
1.1 工程结构
功能:通过父子类工程模拟前后端的联通测试
说明:sca-resource 工程内存放后端文件,sca-resorce-ui工程内存放前端文件
1.2 父子聚合工程
1.2.1.创建父工程
1.2.2.配置依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
1.2.3.创建子工程
前端模拟Ui
后端模拟SSM
1.2.4.配置依赖
前端(客户端)配置依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
后端(资源端)配置依赖
<!--Spring Boot Web (服务-内置tomcat)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Nacos Discovery (服务注册发现)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Nacos Config (配置中心)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--Sentinel (流量防卫兵-限流和熔断)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--Spring Boot 监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
版本控制
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
说明:加入这个注解后idea的编译版本就变为了jdk8
1.2.5.写资源文件
1.服务初始化配置(后端配置,配置文件上传路径)
server:
port: 8881
spring:
application:
name: sca-resource
resources: #定义可以访问到上传资源的路径
static-locations: file:d:/uploads #静态资源路径(原先存储到resources/static目录下的资源可以存储到此目录中)
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
jt:
resource:
path: d:/uploads #设计上传文件存储的根目录(后续要写到配置文件)
host: http://localhost:8881/ #定义上传文件对应的访问服务器
2.启动类
后端文件上传
@SpringBootApplication
public class FileApplication {
public static void main(String[] args) {
SpringApplication.run(FileApplication.class, args);
}
}
前端启动资源
@SpringBootApplication
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication .class, args);
}
}
1.3 聚合工程相关知识点
1.3.1.聚合的概念
把项目的各个模块(子工程)聚合在一起构建。一般用于分模块开发,最后整体打包发布
Maven Project独立运行
Maven Module无法独立运行
1.3.2.聚合工程开发步骤
1.根项目是一个pom项目。
2.子模块:Maven Module
3.子模块中写相应资源,如ui资源中的网页,后端资源的三层架构
注意:聚合打包时(install),选择父工程进行聚合
发布到tomcat运行时(tomcat7:run),选择web工程进行发布运行
1.3.3.工程聚合和继承的区别
聚合是为了方便快速构件项目。对于聚合模块来说,它知道有哪些被聚合的模块,但那些模块不知道这个聚合模块的存在
继承是为了消除重复配置。对于继承关系的父POM来说,它不知道有哪些子模块继承于它,但是子模块必须知道自己的父POM是什么
2.资源项目以及配置文件
2.1 前端资源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上载演示</title>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<form id="fileForm" method="post" enctype="multipart/form-data" onsubmit="return doUpload()">
<div>
<label>上传文件
<input id="uploadFile" type="file" name="uploadFile">
</label>
</div>
<button type="submit">上传文件</button>
</form>
</body>
<script>
//jquery代码的表单提交事件
function doUpload(){
//获得用户选中的所有图片(获得数组)
let files=document.getElementById("uploadFile").files;
if(files.length>0){
//获得用户选中的唯一图片(从数组中取出)
let file=files[0];
//开始上传这个图片
//由于上传代码比较多,不想和这里其它代码干扰,所以定义一个方法调用
upload(file);
}
//阻止表单提交效果
return false;
};
// 将file上传到服务器的方法
function upload(file){
//定义一个表单
let form=new FormData();
//将文件添加到表单中
form.append("uploadFile",file);
//异步提交
let url="http://localhost:8881/resource/upload/";
axios.post(url,form)
.then(function (response){
alert("upload ok")
console.log(response.data);
})
.catch(function (e){//失败时执行catch代码块
console.log(e);
})
}
</script>
</html>
2.2 后端资源
2.2.1 控制层
@Slf4j
@RestController
@RequestMapping("/resource/")
public class ResourceController {
//当了类的上面添加了@Slf4J就不用自己创建下面的日志对象了
// private static final Logger log=
// LoggerFactory.getLogger(ResourceController.class);
@Value("${jt.resource.path}")
private String resourcePath;//="d:/uploads/";
@Value("${jt.resource.host}")
private String resourceHost;//="http://localhost:8881/";
@PostMapping("/upload/")
public String uploadFile(MultipartFile uploadFile) throws IOException {
//1.创建文件存储目录(按时间创建-yyyy/MM/dd)
//1.1获取当前时间的一个目录
String dateDir = DateTimeFormatter.ofPattern("yyyy/MM/dd")
.format(LocalDate.now());
//1.2构建目录文件对象
File uploadFileDir=new File(resourcePath,dateDir);
if(!uploadFileDir.exists())uploadFileDir.mkdirs();
//2.给文件起个名字(尽量不重复)
//2.1获取原文件后缀
String originalFilename=uploadFile.getOriginalFilename();
String ext = originalFilename.substring(
originalFilename.lastIndexOf("."));
//2.2构建新的文件名
String newFilePrefix=UUID.randomUUID().toString();
String newFileName=newFilePrefix+ext;
//3.开始实现文件上传
//3.1构建新的文件对象,指向实际上传的文件最终地址
File file=new File(uploadFileDir,newFileName);
//3.2上传文件(向指定服务位置写文件数据)
uploadFile.transferTo(file);
String fileRealPath=resourceHost+dateDir+"/"+newFileName;
log.debug("fileRealPath {}",fileRealPath);
//后续可以将上传的文件信息写入到数据库?
return fileRealPath;
}
}
说明:控制层书写了文件上传的业务,指定了文件上传的路径,并且构建了新的文件名
2.2.2跨域配置实现
我们在通过客户端工程,访问文件上传服务时,需要进行跨域配置,例如:
@Configuration
public class CorsFilterConfig {
@Bean
public FilterRegistrationBean<CorsFilter> filterFilterRegistrationBean(){
//1.对此过滤器进行配置(跨域设置-url,method)
UrlBasedCorsConfigurationSource configSource=new UrlBasedCorsConfigurationSource();
CorsConfiguration config=new CorsConfiguration();
//允许哪种请求头跨域
config.addAllowedHeader("*");
//允许哪种方法类型跨域 get post delete put
config.addAllowedMethod("*");
// 允许哪些请求源(ip:port)跨域
config.addAllowedOrigin("*");
//是否允许携带cookie跨域
config.setAllowCredentials(true);
//2.注册过滤器并设置其优先级
configSource.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> fBean= new FilterRegistrationBean(new CorsFilter(configSource));
fBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return fBean;
}
说明:此项也可在yml内配置
3.文件项目测试
3.1具体过程
第一步:启动nacos
第二步:启动sca-resource服务
第三步:启动sca-resource-ui服务
第四步:打开浏览器进行访问测试,例如:
3.2文件上传可能出现的错误
1.404资源未找到
解决方案:检查路径是否匹配
3.3流程调用总结
resouce-ui内的html使用axios访问了resource的方法,为上传的文件提供了一个文件夹,并将文件写入,从而实现资源的调用。
4.API网关(Gateway)工程实践
4.1 概述
API 网关是外部资源对服务内部资源访问的入口,所以文件上传请求应该首先请求的是网关服务,然后由网关服务转发到具体的资源服务上。
4.2 服务调用架构
4.3 工程项目结构设计
4.4 创建网关工程及初始化
第一步:创建sca-resource-gateway工程,
第二步:添加项目依赖,
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
第三步:创建配置文件bootstrap.yml,然后进行初始配置
server:
port: 9000
spring:
application:
name: sca-resource-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: localhost:8848
file-extension: yml
gateway:
discovery:
locator:
enabled: true
routes:
- id: router01
uri: lb://sca-resource
predicates:
- Path=/sca/resource/upload/**
filters:
- StripPrefix=1
第四步:构建项目启动类,并进行服务启动,检测是否正确
4.5 网关跨域配置
1.java文件实现
//@Configuration
public class CorsFilterConfig {
@Bean
public CorsWebFilter corsWebFilter(){
//1.构建基于url方式的跨域配置
UrlBasedCorsConfigurationSource source= new UrlBasedCorsConfigurationSource();
//2.进行跨域配置
CorsConfiguration config=new CorsConfiguration();
//2.1允许所有ip:port进行跨域
config.addAllowedOrigin("*");
//2.2允许所有请求头跨域
config.addAllowedHeader("*");
//2.3允许所有请求方式跨域:get,post,..
config.addAllowedMethod("*");
//2.4允许携带有效cookie进行跨域
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
}
2.配置文件实现
spring:
cloud:
gateway:
globalcors: #跨域配置
corsConfigurations:
'[/**]':
allowedOrigins: "*"
allowedHeaders: "*"
allowedMethods: "*"
allowCredentials: true
4.6 启动工程进行服务访问
首先打开网关(Gateway),资源服务器(Resource),客户端工程服务(UI),然后修改fileupload.html文件中访问资源服务端的url,例如:
let url="http://localhost:9999/nacos/resource/upload/";
接下来进行访问测试,例如: