这里先明确三个概念和其关系,
browser 浏览器
office server office的软件
file server 文件管理服务器
下面上图说明下预览的时候的请求流程
简单的解释下:
这里注意几个问题:
1、请求地址的格式别随便改
2、请求地址中filename和返回的Base FileName保持一致会避免很多奇葩的问题存在。
3、getFile请求的时候返回的数据是流的形式返回,如果指定content-type的为
application/octet-stream。那么最好不要用RestController
4、从远程例如阿里OSS获取文件的时候计算文件大小的方法如下:
/**
* 从输入流中获取字节数组
* @param inputStream
* @return
* @throws IOException
*/
private static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
集成代码如下:
Filter实现,集成权限校验
/**
* 处理office的文档预览,Token处理
* @author 大仙
*/
@Slf4j
@WebFilter(filterName = "officeFilter", urlPatterns = "/wopi/*")
public class OfficeFilter implements Filter {
@Autowired
private TokenCheckService authService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("init....");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
String token = request.getParameter("access_token");
if(StringUtils.isBlank(token)){
fail(403,"无权限",response);
return;
}
BaseUser baseUser = AccessTokenUtil.getBaseUserByToken(token);
if(baseUser==null){
fail(403,"无权限",response);
return;
}
if(!authService.checkTokenValid(baseUser,token)){
fail(403,"无权限",response);
return;
}
log.info("执行");
servletRequest.setAttribute("userName",baseUser.getName());
chain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
log.info("destroy....");
}
/**
* 失败处理
* @param code
* @param message
* @param response
* @throws Exception
*/
private void fail(Integer code,String message,HttpServletResponse response) throws IOException{
response.setStatus(403);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(JSONObject.toJSONString(CommonResponse.successResponse("无权限")));
}
}
第二步:checkFileInfo的实现
@Override
public String getFileInfo(String fileId, HttpServletRequest request) {
logger.info("开始获取文件数据");
if(StringUtils.isBlank(fileId)){
throw new OrganException("文件ID不能为空");
}
fileId = fileId.substring(0,fileId.lastIndexOf("."));
Long id = Long.parseLong(fileId);
LessonContent lessonContent = lessonContentDao.getById(id);
if(lessonContent==null){
throw new OrganException("id不存在,非法请求");
}
String pptUrl = lessonContent.getPptUrl();
String handUrl = lessonContent.getHandbookUrl();
if(StringUtils.isBlank(pptUrl)&&StringUtils.isBlank(handUrl)){
throw new OrganException("无需要预览的内容");
}
//获取最终预览的文件
String fileUrl = pptUrl==null?handUrl:pptUrl;
JSONObject result = new JSONObject();
String BaseFileName=id+""+fileUrl.substring(fileUrl.lastIndexOf("."));
String ownerId = "admin";
String version = lessonContent.getCreateDate().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
Integer size = 0;
try {
URL url = new URL(fileUrl);
InputStream is = url.openStream();
byte[] bytes = readInputStream(is);
size = bytes.length;
}catch (Exception e){
logger.error("读取文件出错");
}
return "{\"BaseFileName\":\"" + BaseFileName + "\",\"OwnerId\":\"" + ownerId + "\",\"Size\":\"" + size
+ "\",\"AllowExternalMarketplace\":\"" + true + "\",\"Version\":\"" + version + "\"}";
}
第三步:getFile实现
@Override
public HttpServletResponse getFile(HttpServletResponse response, String fileId) {
logger.info("开始获取文件数据--数据流");
if(StringUtils.isBlank(fileId)){
throw new OrganException("文件ID不能为空");
}
fileId = fileId.substring(0,fileId.lastIndexOf("."));
Long id = Long.parseLong(fileId);
LessonContent lessonContent = lessonContentDao.getById(id);
if(lessonContent==null){
throw new OrganException("id不存在,非法请求");
}
String pptUrl = lessonContent.getPptUrl();
String handUrl = lessonContent.getHandbookUrl();
if(StringUtils.isBlank(pptUrl)&&StringUtils.isBlank(handUrl)){
throw new OrganException("无需要预览的内容");
}
//获取最终预览的文件
String fileUrl = pptUrl==null?handUrl:pptUrl;
String BaseFileName=id+""+fileUrl.substring(fileUrl.lastIndexOf("."));
try {
URL url = new URL(fileUrl);
InputStream fis = url.openStream();
String contentType = "application/octet-stream";
byte[] buffer = readInputStream(fis);
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.addHeader("Content-Disposition","attachment;filename=" + new String(BaseFileName.getBytes("utf-8"), "ISO-8859-1"));
response.addHeader("Content-Length", "" + buffer.length);
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType(contentType);
toClient.write(buffer);
toClient.flush();
toClient.close();
}catch (Exception e){
logger.error("读取文件出错");
}
return response;
}
zhuwei_clark 发布了150 篇原创文章 · 获赞 36 · 访问量 14万+ 私信 关注