Java文件上传实例并解决跨域问题
目录
每次上传文件都会经过网关,必然会给网关带来很大的压力,那我们如何绕过网关呢?
1.在网关中配置白名单 ,这样也会走网关,只是压力少了一点点
2.在nginx做转发,当请求文件上传时,直接转到相应的服务
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传功能的实现。
我们实现文件的上传用到了Spring-web框架中的 MultipartFile接口,MultipartFile接口的源码注释中说“MultipartFile接口是 在大部分请求中接收的上载文件的表示形式。”
A representation of an uploaded file received in a multipart request.
The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired. The temporary storage will be cleared at the end of request processing.
常用方法如下表
Method Summary | ||
---|---|---|
byte[] |
获取文件的字节数组 | getBytes() Return the contents of the file as an array of bytes. |
String |
获取文件的类型 | getContentType() Return the content type of the file. |
InputStream |
获取文件的输入流 | getInputStream() Return an InputStream to read the contents of the file from. |
String |
获取文件名 | getName() Return the name of the parameter in the multipart form. |
String |
获取原始文件名(防止篡改文件类型) | getOriginalFilename() Return the original filename in the client's filesystem. |
long |
获取文件的大小,以字节的形式) | getSize() Return the size of the file in bytes. |
boolean |
判断文件是否为空 | isEmpty() Return whether the uploaded file is empty, that is, either no file has been chosen in the multipart form or the chosen file has no content. |
void |
将接收到的文件传输到给定的目标文件。 | transferTo(File dest) Transfer the received file to the given destination file. |
/**
* @Author: 小小张自由
* @Date: 2021/7/6 - 20:56
* @Description: 文件上传
* @version: 1.0
*/
@Controller
@RequestMapping("upload")
public class UploadController {
@Autowired
private UploadService uploadService;
@PostMapping("image")
public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file){
String url= this.uploadService.uploadImage(file);
if (StringUtils.isBlank(url)){
return ResponseEntity.badRequest().build();
}
return ResponseEntity.status(HttpStatus.CREATED).body(url);
}
}
/**
* @Author: 小小张自由
* @Date: 2021/7/6 - 21:01
* @Description: 文件上传
* @version: 1.0
*/
@Service
public class UploadService {
//用于判断文件的类型,暂时只判断了“image/gif","image/jpeg”
private static final List<String> CONTENT_TYPES= Arrays.asList("image/gif","image/jpeg");
private static final Logger LOGGER= LoggerFactory.getLogger(UploadService.class);
/**
* 业务逻辑代码
* @param file 文件的存储的url
* @return
*/
public String uploadImage(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
//校验文件类型
//方法一:截取字符串
String afterLast = StringUtils.substringAfterLast(".", originalFilename);
//方法二:使用getContentType方法
String contentType = file.getContentType();
if (!CONTENT_TYPES.contains(contentType)){
LOGGER.info("文件类型不合法:"+originalFilename);
return null;
}
//校验文件内容
try {
//获取文件流
BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
if (bufferedImage==null){
LOGGER.info("文件内容不合法:{}",originalFilename);
return null;
}
//保存到服务器 E:\Leyou\image
//将接收到的文件传输到给定的目标文件。
file.transferTo(new File("E:\\Leyou\\Image\\"+originalFilename));
//返回URL,进行回显
//可以使用Nginx-图片服务器
return "http://image.leyou.com/"+originalFilename;
} catch (Exception e) {
LOGGER.info("服务器内部错误:"+originalFilename);
e.printStackTrace();
}
return null;
}
}
修改Nginx的配置文件nginx.conf,监听80端口,设置root的值为:E盘
- 图片不能保存在服务器内部,这样会对服务器产生额外的加载负担
- 一般静态资源都应该使用独立域名,这样访问静态资源时不会携带一些不必要的cookie,减小请求的数据量
server {
listen 80;
server_name image.leyou.com;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
root E:\\Leyou\\image;
}
}
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {
//白名单:存放放行的URL
private List<String> allowPaths;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取请求的url路径
String path = request.getURI().getPath();
boolean flag=isAllowPath(path);
if (flag) {
log.info("请求在白名单中,leyou.filter: {}",path);
//放行
return chain.filter(exchange);
} else {
//写其他的业务逻辑
~~~~
}
}
private boolean isAllowPath(String path) {
//判断是否允许放行
if (allowPaths.contains(path)){
return true;
}
return false;
}
本实例使用了方法二、需要增加配置
server {
listen 80;
server_name api.leyou.com;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 新增加的配置,用于文件上传
location /api/upload {
proxy_pass http://127.0.0.1:8082;
proxy_connect_timeout 600;
proxy_read_timeout 600;
rewrite "^/api/(.*)$" /$1 break;
}
# 网关的配置
location / {
proxy_pass http://127.0.0.1:10010;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
}
当这样配置之后,文件上传就不会过网关,减少了网关的压力。但是有引来了一个新问题那就是跨域。
由于Nginx将文件上传的请求直接转发到了具体服务中,不再走gateway,所以gateway中的跨域配置,不再生效了。 需要在文件上传这个服务中单独配置跨域。
/**
* @Author: 小小张自由
* @Date: 2021/6/15 - 11:12
* @Description: 解决 跨域问题
* @version: 1.0
*/
@Configuration
public class LeyouCorsConfiguration {
@Bean
public CorsFilter corsFilter(){
//初始化配置对象
CorsConfiguration configuration = new CorsConfiguration();
//允许跨域访问的域名
configuration.addAllowedOrigin("*");
// configuration.setAllowCredentials(true); //运行携带cookie
configuration.addAllowedMethod("*"); //代表所有请求方法
configuration.addAllowedHeader("*"); //允许携带任何头信息
//初始化cors配置源对象
UrlBasedCorsConfigurationSource configurationSource=new UrlBasedCorsConfigurationSource();
configurationSource.registerCorsConfiguration("/**",configuration);
//返回CorSfilter实例,参数
return new CorsFilter(configurationSource);
}
}
到此应该就可以上传了,但是还是报跨域,我已经配置好了啊,为什么还是报跨域呢?
我就想是不是Nginx的问题,然后我就一行一行的读配置,最后发现
nginx配置中没有配置请求实体大小
加上这行配置就好了
client_max_body_size 1024m;
文章浏览阅读1k次。这个必须记一笔:今天在安装配置完hive后,进入了hive的命令行执行show databases时抛出一下错误:FAILED: Error in metadata: MetaException(message:Got exception: java.net.ConnectException Call to hadoop0/192.168.0.10:9000 failed on c_caused by: metaexception(message:got exception: java.net.connectexception ca
文章浏览阅读8.8w次,点赞140次,收藏772次。工欲善其事,必先利其器。想要提升编程开发效率,必须选择一款顺手的开发工具。JetBrains 公司提供了一系列功能强大、风格统一的开发工具,深受开发者喜爱。其中,IDEA 是面向 Java 开发的专业 IDE(集成开发环境),90% 以上的企业都在使用 IDEA 进行 Java 开发,而不是用其他的工具如 Eclipse。但是,想要开发效率最大化,仅有好的开发工具是不够的,还要能够熟练地使用它。对于 IDEA 的新用户来说,面对功能如此丰富的开发工具可能会有些迷茫,但又不想花时间去学习如何使用,_idea好用的插件
文章浏览阅读1.9k次。2019独角兽企业重金招聘Python工程师标准>>> ..._跑monkey命令
文章浏览阅读1.2w次,点赞6次,收藏71次。**前言**Xilinx提供了这样的IP核,名为MIG(Memory Interface Generator),它可以为提供DDR3、DDR4等多种存储器提供接口。本次DDR4读写采用的就是这个IP核,不过7系的FPGA与UltraScale系的FPGA所所对应的MIG IP核在客制化上有所区别,本文暂且只讨论UltraScale+系列FPGA所对应的MIG IP核,并且只针对DDR4的使用。..._fpga ddr4 读写测试 xilinx
文章浏览阅读1.8k次。这个问题困扰了我一天的时间。首先简单说明以下,我前端请求一开始用的POST,请求代码片段如下:export const postRequest = (url, params) => { let accessToken = getStore("accessToken"); return axios({ method: 'post', url: `${base}${url}`, data: params, trans_设置searchform表单指定错误或url为空。
文章浏览阅读4.9k次。在上一片博客中已经讲述了如何定位,这里主要讲根据数据源来添加覆盖物,在百度的demo中就只是演示了他固定添加了几个覆盖物,但是在实际项目中需要添加的添加的覆盖物就不是固定的,需要根据list集合数据源来添加,并且需要为这些覆盖物添加上对应的点击事件。 markers=new Marker[rodlist.size()]; for (int i=0;i
文章浏览阅读370次。I use GetAdaptersInfo to get MAC addresses of interfaces. GetAdaptersInfo exist on old and new versions of Windows. But msdn warns : "On Windows XP and later: Use the GetAdaptersAddresses ..._hook getadaptersaddresses崩溃
文章浏览阅读1.3w次。生命不止,继续Go go go.变量介绍完了,流程控制介绍完了,也该轮到函数了。 go中,使用关键字func进行函数声明:func function_name( [parameter list] ) [return_types]{ body of the function}比如,声明一个函数,交换两个字符串:func swap(x, y string) (string, string) {_unexpected swap, expecting (
文章浏览阅读3.2k次。服务器是重要的网络设备,很多人在使用服务器建立网站的时候,都想要自己进行搭建。服务器是为我们提供不间断的互联网应用以及服务的主机,能起到为我们提供文件上传,数据保存,应用服务或网站浏览等作用,其实不是机房要用服务器,而是服务器需要机房,将服务器放在机房,是为了统一管理,节省资源,使其提供的服务更稳定。如何搭建服务器一、开启FTP服务,并建立FTP网站1.打开控制面板,找到程序和功能,点击“启用或者关闭windows功能”。2.把箭头所指的地方都打上勾,然会点击确定,等待配置结束。3.回到控制面板_科学搭建服务器
文章浏览阅读3.3w次,点赞61次,收藏518次。python中groupby函数详解(非常容易懂)一、groupby 能做什么?python中groupby函数主要的作用是进行数据的分组以及分组后地组内运算!对于数据的分组和分组运算主要是指groupby函数的应用,具体函数的规则如下:df.groupby([df[属性],df[属性])(指分类的属性,数据的限定定语,可以有多个).mean()(对于数据的计算方式——函数名称)举例如下:print(df[“评分”].groupby([df[“地区”],df[“类型”]]).mean())#上_groupby怎么用python
文章浏览阅读969次。_windows7怎么关闭所有杀毒软件
文章浏览阅读1.2k次。启动spring boot报错: To display the conditions report re-run your application with 'debug' enable端口被占用了 修改 server.port= 31001解决_to display the conditions report re-run your application with 'debug' enable