Liferay 6.1开发学习(十二):文件上传处理

一、在portlet中取到上传的文件

这两的获取有两种方法,一种是普通的fileupload的处理方法,一种是使用liferayAPI

1、使用fileupload的处理方法:

此种方法的获取和在普通的servlet里面使用fileupload的方法一样,核心代码如下 :

DiskFileItemFactory factory = new DiskFileItemFactory();
 //PortletFileUpload upload = new PortletFileUpload(factory); 
 ServletFileUpload upload = new ServletFileUpload(factory);
 upload.setSizeMax(1024 * 1024 * 200);
 HttpServletRequest servletRequest = PortalUtil.getHttpServletRequest(request);
 List<FileItem> items = upload.parseRequest(servletRequest);

注:也可以使用此行代码,如果使用了此行则下面的HttpServletRequest servletRequest = PortalUtil.getHttpServletRequest(request)就可以不要,在upload.parseRequest里面传actionRequest。但是此方法在weblogic环境下面会出错,所以如果要在weblogic下面运行,请使用下面的servletFileUpload

其他代码就和在普通的Servlet里面使用fileupload一样,这里不再多写。

2、使用LiferayAPI获取上传文件

推荐使用下面的代码进行文件上传。

UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(actionRequest);
 String sourceFileName = uploadPortletRequest.getFileName("file");
 String contentType = uploadPortletRequest.getContentType("file");
 long size = uploadPortletRequest.getSize("file");
// File file = uploadPortletRequest.getFile("file");
 InputStream is = uploadPortletRequest.getFileAsStream("file");

:其中的getFileName中的file<input type="file" name="file">中的name值,具体的可以要看自己的调整。

二、将获取到的文件上传到Liferay的文档库

1、上传文件

portlet中获取到我们上传的文件,只算是完成了第一步。取到了上传的文件,怎么传到Liferay的文件库中呢?使用如下的接口

DLAppLocalServiceUtil.addFileEntry(long userId, long repositoryId, long folderId,java.lang.String sourceFileName, java.lang.String mimeType,java.lang.String title, java.lang.String description,java.lang.String changeLog, byte[] bytes,com.liferay.portal.service.ServiceContext serviceContext)

此接口的参数逐个说明:

long userId上传此文件的用户id

long repositoryId仓库存储ID,此ID一般为groupid

long folderId:文件夹ID,可以自己创建,或使用liferay默认的如:DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT等,最好是自己根据上传资源的情况分类,如新闻的存到新闻文件,博客的存成博客文件等

String sourceFileName上传文件的源文件名

String mimeType算是文件类型,可以使用mimeType = MimeTypesUtil.getContentType(fileName);根据文件名获取。

String title文件标题,这个与SourceFileName的区别在于,此title是最终显示在系统上的,可以由用户输入,源文件名称是上传获取的文件名称,不能手动改变。可以留空。

String description关于此文件的描述,可以留空。

String changeLog文件修改日志,可以留空。

byte[] bytes文件的正文件,字节数组。

ServiceContext serviceContext此类可以通过以下代码

ServiceContext serviceContext = ServiceContextFactory.getInstance(DLFileEntry.class.getName(), request);

获取。此对象里面包含了一些环境信息,如groupidcompanyid,权限,门户路径,当前语言,userId等信息。

在实际应用中可以自己将上面的这个接口再做一层封装,作为一个公共的文件上传接口,以供其他需要文件上传的地方调用,具体的请自行封装,这里就不再帖我封装的代码。

2、获取文件路径

上面的文件上传之后返回的是一个FileEntry的对象,如果获取到上传的文件的路径呢,方法如下,可以定义一个方法,用来返回文件路径,此方法对图片、各式文件都是有效。

public static String getFilePath(FileEntry fileEntry) {
 if (null!=fileEntry) {
 return "/documents/" + fileEntry.getRepositoryId() + "/" + fileEntry.getFolderId() + "/"
 + HttpUtil.encodeURL(HtmlUtil.unescape(fileEntry.getTitle()), true) + "/" + fileEntry.getUuid();
 }else {
 //如有需要,此处可以定义一个默认图片
 return StringPool.BLANK;
 }

或者下面的这个方法,下面的这个更简便一些

public static String getFilePath(FileEntry fileEntry) {
 if (null!=fileEntry) {
 return "/documents/" + fileEntry.getRepositoryId() + "/" + fileEntry.getUuid();
 }else {
 //如有需要,此处可以定义一个默认图片
 return StringPool.BLANK;
 }

有时候如果文件是一个图片,上传的图片可以很大,如何获取一个缩略图呢?如下:

public static String getSmallImagePath(FileEntry fileEntry){
String path = getFilePath(fileEntry);
return path+"?imageThumbnail=1";
}

FastJSON使用技巧两则

FastJSON是阿里的温少写的,详细介绍请看:http://code.alibabatech.com/wiki/pages/viewpage.action?pageId=2424946。具有高性能、支持标准、依赖少的方便之处。

1、字段名称映射

比如现在JavaBean中有一个字段名称为parentId,想将此字段转换为pId,则可以使用如下代码。

NameFilter filter = new NameFilter() { 
 public String process(Object source, String name, Object value) {
 if (name.equals("parentId")) {
 return "pId";
 }
 
 return name;
 }
 
 };
 
 String jsonString = StringUtils.EMPTY;
 SerializeWriter out = new SerializeWriter();
 try {
 JSONSerializer serializer = new JSONSerializer(out);
 serializer.getNameFilters().add(filter);
 serializer.write(columns);//这里的columns为待转换的对象
 jsonString = out.toString();
 } finally {
 out.close();
 }

2、去除JSON中的key值的引号

FastJSON中默认为转换后的JSON中的key值是带引号的,有些特殊情况或者组件需要不带引号的,可以使用下面的代码将引号去掉。
在上面的代码中添加下面的这行代码,则可以将转换后的字段名称的引号去掉。
serializer.config(SerializerFeature.QuoteFieldNames, false);

Liferay6.1简单增删改查示例

(建立了一个讨论Liferay的群:6537876,探讨学习Liferay的二次开发、Portal技术、企业信息门户(EIP)等相关内容,欢迎加入。)

写了一个最简单的portlet的增删改查的示例。下载地址:点击这里


portlet的创建,可以参考:

Liferay 6.1开发学习(二):创建一个Portlet工程

Liferay 6.1开发学习(三):Portlet简述

ServiceBuilder的使用,可以参考:Liferay 6.1开发学习(四):Service Builder

说明:

demo演示的是最简单的一个增删改查,没有写css,页面中数据提交前没有做javascript的非空验证,数据的删除没有对用户进行提醒,在实际的开发环境中请注意以上细节。

可能碰到的问题

问题1:不会跳转页面

如果是看完demo,自己开发中可能遇到,点击了添加不会跳转到相关页面。请检查portlet.xml中是否有下面的配置:

<init-param>
 <name>copy-request-parameters</name>
 <value>true</value>
 </init-param>

问题2:显示SDK不正确,SDK不能配置等

请将下载的源码工程,解压后复制到SDKportlets目录下面,然后再使用Eclipse导入,在导入的时候不要勾选复制工程到workspace的选项。

从常见文档中提取纯文本内容

要想使用Lucene检索office文档(wordexcelppt等)、PDFHTML文档,通常的处理策略是先从这些文档中提取出纯文本,然后再进行相关索引处理等。

一、从office中提取纯文本

office文件中提取纯文本,可以使用POIhttp://poi.apache.org/),最新版本为3.8。从office文件中提取纯文本方法很简单。只需要两行代码即可。

POITextExtractor extractor = ExtractorFactory.createExtractor(is);
 String contents = extractor.getText();

第一行中传入的is参数为office文件的inputstream。这里不分wordexcle还是ppt,不区分03版还是07版,只需要将文件的inputStream传入此方法中。再使用extractor.getText()。得到的即为office文件的纯文本数据。

注意:有时候可能由于文件的源访问,导致提取的纯文本里面有一些特殊字符,可以使用下面的方法过滤掉。

/**
 * 过滤特殊字符
 * 
 * @param contents
 * @return
 */
 public static String filterSpecialChar(String contents) {
 contents = contents.replace('\u0003', '\u0000');
 contents = contents.replace('\u0004', '\u0000');
 contents = contents.replace('\u000b', '\u0000');
 contents = contents.replace('\u000c', '\u0000');
 contents = contents.replace('\u0007', '\u0000');
 contents = contents.replace('\u0008', '\u0000');
 contents = contents.replace('\u0013', '\u0000');
 contents = contents.replace('\u0014', '\u0000');
 contents = contents.replace('\u0015', '\u0000');
 contents = contents.replace('\u0016', '\u0000');
 contents = contents.replace('\u0020', '\u0000');
 return contents;
 }

二、从PDF中提取纯文本

PDF中提取纯文本,可以使用PDFBox组件(http://pdfbox.apache.org/,最新版本为1.7.1。需要的jar包为:pdfboxfontboxjempbox等,最好再加上pdfbox-lucene

如果使用了pdfbox-lucene的包,则不用自己写pdfbox的处理方法,直接调用相关方法(LucenePDFDocument类里面)就行了,这里介绍,如何手写实现,也很简单。

PDDocument pdfDocument = PDDocument.load(is);
if (pdfDocument.isEncrypted()) {
 // 仅仅尝试使用默认密码打开加密的PDF
 pdfDocument.decrypt("");
 }
// 创建一个writer用来作来存储文件正文
 StringWriter writer = new StringWriter();
 if (stripper == null) {
 stripper = new PDFTextStripper();
 } else {
 stripper.resetEngine();
 }
 stripper.writeText(pdfDocument, writer);
String contents = writer.getBuffer().toString();

上面is同样为PDF文件的inputStream。下面的contents为提取到的PDF的纯文本内容。

三、从HTML文件中提取正文

HTML文件中提取正文,简单说就是去除HTML文件中的HTML标签,这处常用的方法有许多,如使用正则表达式、html parse等。这里我们使用JSOUP,这个更方便快捷。可以参考我以前写的一篇文章:使用JSOUP处理HTML文档

在获取到Document之后,使用String text = document.text(); 即可获取到纯文本数据。

你可能感兴趣的:(Liferay 6.1开发学习(十二):文件上传处理)