参考:
参考:
或者叫 分片传输,分片方案不一定用于浏览器上传服务端,也可以用于服务端到服务端,甚至服务端到客户端 (下载)
浏览器 -> 服务端
浏览器切割文件为n个切片,调用n次服务端上传接口,上传n个切片,
服务端接收切片,每次接收,内存中暂存每个切片,每接收到一个切片,则以 appendWrite 的方式追加到目标文件中(可以顺序appendWrite到文件末尾,保证接收切片的顺序正确,如果中间丢失某个切片,则响应浏览器切片序号,重传此切片;也可以计算偏移量,将切片插入目标文件中)
将文件切分为 n 个切片,除了最后一个切片外。其余每个切片固定 sliceSize 大小 切片序号: 0, 1, 2, 3,... 切片 在此文件中的偏移量 = 切片序号 * 单个切片大小 文件接收完时 (/合并时) 方案1:由前端发起http,告诉服务端合并切片 方案2: 第一次发送文件检查md5时,发送文件总大小,服务端记录下来,此后切片传输时,可通过 切片个数,文件总大小,切片大小,计算出什么时候文件接收完成,这时合并切片 缺:此种方法,需要一个临时路径用于存一个临时文件(上传一个文件时) 优:假设 appendWrite 时 为顺序插入切片,则无需数据库支持(保存切片序号信息),也可以记录上传进度,上传中断后,不清除临时文件,下次用户可以接着上传,结合临时文件的大小,与保存在数据库中的文件总大小,切片单个大小,计算出,当前位于第几个切片,需要从第几个切片处开始上传,则响应浏览器,上传对应切片 当浏览器上传切片时,服务端响应此切片上传成功后,浏览器可以记录此切片已上传成功,并更新上传进度条
服务单接收切片,每接收到一个切片,则将此切片存于 /md5file/part-2.tmp
(单独的切片文件) 磁盘中,保存最后一个切片后,合并切片为一个文件,完成后清除切片文件,
缺:此种方法,需要一个临时路径用于存n个切片文件(上传一个文件时,需要n个切片文件) 优:1.由于是将切片保存到磁盘中,因此,可以断点续传,上传中断后,不清除切片文件,下次用户可以接着上传。 由于每个切片文件,文件名中包含了切片序号,因此无需数据库支持(保存切片序号),也不需要顺序支持
一个理想的方案:应当是在 文件上传检查(md5检查)时,响应切片大小,前端使用此切片大小切片,这样只需要维护服务端对于切片大小的配置即可。
参考:
"Content-Disposition","attachment;filename=FileName.txt"
attachment
表示以附件方式下载,而不是直接用浏览器打开查看
当你在响应类型为
application/octet- stream
情况下使用了这个头信息的话,那就意味着你不想直接显示内容,而是弹出一个"文件下载"的对话框,接下来就是由你来决定"打开"还是"保存" 了
参考:
POST 提交数据的方式, 浏览器的原生
<form>
表单,如果不设置enctype
属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
key 和 val 都进行了 URL 转码 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」
POST 数据提交的方式, 使用表单上传文件时,必须让
<form>
表单的enctype
等于 multipart/form-data
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
内容以 json字符串 格式组织,放于请求体
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>
Q: 服务端如何提供大文件下载? A: Q: 服务端提供视频播放直链,难道直接一次性将文件内容返回,这样不是很占用服务端内存吗?是否改切片传输给浏览器? A: Q: 针对大文件上传使用 切片上传,如果对接其它云存储(eg, _阿里云_OSS), 方案1:直接服务端(内存中)接收切片,直接传输到OSS,最后在 OSS 中合并切片 方案2:n个切片暂存在服务端磁盘中,合并后,再(边读边写)传输给OSS 方案3:直接服务端(内存中)接收切片,直接传输到OSS,以追加到文件末尾方式 写入OSS 单个文件,写完即合并完 各种方案利弊? A: Q: 边读边写?追加到文件末尾? A: 其实 while (追加到文件末尾) 的方式,就是 边读边写, 不过边读边写,没有强调插入位置(不一定要插入末尾),而 追加到文件末尾强调了插入位置在最后
org.apache.hadoop.ipc.RemoteException: File /epan-hdfs/2021/06/20/e4133d04-5c6f-465c-911b-7b9da25c8e56 could only be replicated to 0 nodes instead of minReplication (=1). There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:1571)
解决:
Configuration conf = new Configuration();
conf.set("dfs.client.use.datanode.hostname", "true");
fs = FileSystem.get(URI.create(hdfsURI), conf);
设置 Windows host 映射
# Docker - Hadoop
127.0.0.1 master
Docker 容器端口开放 50075
参考:
注意: 目测
目测主要是50010 端口 用于 宿主机访问 DataNode
成功 最终代码:
Configuration conf = new Configuration();
conf.set("dfs.client.use.datanode.hostname", "true");
conf.set("dfs.replication", "1");
fs = FileSystem.get(URI.create(hdfsURI), conf);
Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources) on project epan: Input length = 1 -> [Help 1]
解决:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
plugins标签添加 maven-resources-plugin依赖
参考:
The POM for com.alibaba:druid:jar:1.1.21 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
解决:
将driud的依赖从1.2.21降到1.2.20及以下
<!-- Druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
参考:
{
"timestamp": "2021-06-21T02:55:50.737+00:00",
"status": 415,
"error": "Unsupported Media Type",
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* "trace": "org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:206)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:652)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:733)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)\r\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.base/java.lang.Thread.run(Thread.java:832)\r\n",
*/
"message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
"path": "//api/file/uploadCheck"
}
不是:@RequestBody
改为 @RequestParam
,而是
当需要从请求体中取 json格式数据时,使用 @RequestBody
,并且将前端请求时的Content-Type
改为 application/json
参考:
Java:
Date
类有具体时间,但 MySQL 中date
类型只有日期,需要更改为datetime
参考:
通信hadoop平台需要开通的端口
参考:
进入 mysql
mysql -u root -p
操作mysql系统数据库
use mysql
查询用户表
select User,authentication_string,Host from user;
从上面,可以发现
root
为localhost
,即只允许本地访问,设置允许所有访问,即%
授权 这里的123456为你给新增权限用户设置的密码,%代表所有主机,也可以具体到你的主机ip地址
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456';
刷新权限
flush privileges;
再次查询,发现多了一个用户,此时,允许所有远程访问
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'epan_moeci_com.userInfo' doesn't exist
### The error may exist in file [F:\Com\me\Repos\epan\target\classes\mapper\UserMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select id, userName, password, diskSize, usedDiskSize, ipAddress, createTime from userInfo where userName = ?
### Cause: java.sql.SQLSyntaxErrorException: Table 'epan_moeci_com.userInfo' doesn't exist
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Table 'epan_moeci_com.userInfo' doesn't exist] with root cause
解决:
原因1 因为数据库对表的大小写设置问题,设置忽略大小写即可, 在服务运行目录找到my.ini或者my.cnf文件 打开文件,找到mysqld在下面增加一行 lower_case_table_names=1 (0:大小写敏感;1:大小写不敏感) 重启MySQL服务 原因2 可能是多个数据库存在相同表, 因此在导入
install.sql
时,尤其注意,SQLyog
在导出 sql 时, 有CREATE DATABASE
语句,会创建新数据库,而不是导入目标数据库
PPT制作
感谢帮助!
本文作者: yiyun
本文链接: https://cloud.tencent.com/developer/article/1970865
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!