2021SC@SDUSC
目录
一、filecontroller分析:
该类添加了@RestController注解,在Spring中@RestController的作用等同于@Controller + @ResponseBody。
该类中每个方法前都有一个@RequestMapping注解,这个注解是用来映射请求的,即指明处理器可以处理哪些URL请求,该注解既可以用在类上,也可以用在方法上。相当于Servlet中在web.xml中做如下配置:
当使用该注解标记控制器类时,方法的请求地址是相对类的请求地址而言的;当没有使用@RequestMapping标记类时,方法的请求地址是绝对路径。@RequestMapping的地址可以是url变量,通过@PathVariable注解获取作为方法的参数。也可以是通配符来筛选请求地址。
当@RequestMapping(value = "xxx")注解在方法上时,value属性指定了该方法可以处理的 URL 请求路径则是 http://localhost/SpringMVC/xxx,如本类中,fileUpload()添加了@RequestMapping(value = "fileUpload", method = RequestMethod.POST),可以处理的URL请求路径则是http://localhost/SpringMVC/fileUpload。
在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式,这里指定fileUpload只能处理POST方法。
deleteFile方法指定接收的url请求路径是http://localhost/SpringMVC/deleteFile,getFiles方法指定可以处理的url请求路径是http://localhost/SpringMVC/deleteFile,两个方法都设定了只能处理GET请求。
@RequestMapping(value = "fileUpload", method = RequestMethod.POST)
public String fileUpload(@RequestParam("file") MultipartFile file) throws JsonProcessingException {}
@RequestMapping(value = "deleteFile", method = RequestMethod.GET)
public String deleteFile(String fileName) throws JsonProcessingException{}
@RequestMapping(value = "listFiles", method = RequestMethod.GET)
public String getFiles() throws JsonProcessingException {}
这三个方法的具体实现在我们组中另一位分析文件打开的同学的博客里有详细说明,我就不在这里赘述了,分析这个类的初衷是这个类是文件转换的基础,而Spring MVC的框架设计非常巧妙。
二、OnlinePreviewController分析:
该类添加了@Controller注解,标明是一个控制类。在类中声明了如下变量。这是文件转换之前的处理工作,通过在这里分析文件类型来选择工作对象。
private final FilePreviewFactory previewFactory;// 工厂类,处理文件的接口
private final CacheService cacheService;// 缓冲管理
private final FileHandlerService fileHandlerService;// 提供文件处理服务
private final OtherFilePreviewImpl otherFilePreview;
1. onlinePreview:
接收并处理来自url路径 http://localhost/SpringMVC/onlinePreview的请求,这也意味着这个类负责实现文件在线浏览的功能。接收到请求后先分析路径是否合理,若不合理则报错,并交给otherFilePreview来处理,若正确则调用FiewHandlerService对象的getFileAttribute方法获取文件属性,也就是文件的类型,来决定之后的处理,getFileAttribute最后返回一个FileAttribute对象。
@RequestMapping(value = "/onlinePreview")
public String onlinePreview(String url, Model model, HttpServletRequest req) {
String fileUrl;
try {
fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
} catch (Exception ex) {
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
return otherFilePreview.notSupportedFile(model, errorMsg);
}
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl, req);
model.addAttribute("file", fileAttribute);
FilePreview filePreview = previewFactory.get(fileAttribute);
logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
}
2.getFileAttribute
在该方法中,通过model文件夹下自定义的FileAttribute文件分析属性,FileAttribute是作者自定义的类,作为一个文件对象,将文件的各种属性比如FileType type,suffix,name,url,fileKey等封装起来,通过FileAttribute中的方法获取,体现了面向对象的设计思想,降低耦合提高内聚,保护数据安全。而所有的文件判别类型都定义在config文件夹下的config constants中,作为全局通用的标识判断。
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
public static final String DEFAULT_OFFICE_PREVIEW_TYPE = "image";
获取文件属性之后将文件属性对象加入model,之后调用FilePreviewFactory对象的get(FileAttribute)方法,获取文件预览实例。
3.picturesPreview
该方法负责接收并处理来自url路径 http://localhost/SpringMVC/picturesPreview的请求,意味这个类负责实现图片在线浏览的功能。前六行的代码实现和上一个方法相同,也是先分析url是否合格,之后抽取文件并返回文件列表。
@RequestMapping(value = "/picturesPreview")
public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
String fileUrls;
try {
fileUrls = new String(Base64.decodeBase64(urls));
} catch (Exception ex) {
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "urls");
return otherFilePreview.notSupportedFile(model, errorMsg);
}
logger.info("预览文件url:{},urls:{}", fileUrls, urls);
// 抽取文件并返回文件列表
String[] images = fileUrls.split("\\|");
List<String> imgUrls = Arrays.asList(images);
model.addAttribute("imgUrls", imgUrls);
String currentUrl = req.getParameter("currentUrl");
if (StringUtils.hasText(currentUrl)) {
String decodedCurrentUrl = new String(Base64.decodeBase64(currentUrl));
model.addAttribute("currentUrl", decodedCurrentUrl);
} else {
model.addAttribute("currentUrl", imgUrls.get(0));
}
return PICTURE_FILE_PREVIEW_PAGE;
}
区别在之后的代码主要就是处理图片了,先声明一个存放图片url的List<String>对象,存放传入的、要处理的图片,因为已经知道文件属性了,所以不需再调用FileHandlerService的getAttribute方法来获取文件属性了。为model添加imgurls,最后返回PICTURE_FILE_PREVIEW_ PAGE字符串。
4. getCorsFile
该方法根据url获取文件内容,当pdfjs读取存在跨域问题的文件时将通过此接口读取。在try语句中声明url变量、byte数组,通过这个读取文件。
@RequestMapping(value = "/getCorsFile", method = RequestMethod.GET)
public void getCorsFile(String urlPath, HttpServletResponse response) {
logger.info("下载跨域pdf文件url:{}", urlPath);
try {
URL url = WebUtils.normalizedURL(urlPath);
byte[] bytes = NetUtil.downloadBytes(url.toString());
IOUtils.write(bytes, response.getOutputStream());
} catch (IOException | GalimatiasParseException e) {
logger.error("下载跨域pdf文件异常,url:{}", urlPath, e);
}
}