一、在portlet中取到上传的文件
这两的获取有两种方法,一种是普通的fileupload的处理方法,一种是使用liferay的API
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、使用Liferay的API获取上传文件
推荐使用下面的代码进行文件上传。
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);
获取。此对象里面包含了一些环境信息,如groupid,companyid,权限,门户路径,当前语言,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工程
和
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不能配置等
请将下载的源码工程,解压后复制到SDK的portlets目录下面,然后再使用Eclipse导入,在导入的时候不要勾选复制工程到workspace的选项。
从常见文档中提取纯文本内容
要想使用Lucene检索office文档(word、excel、ppt等)、PDF、HTML文档,通常的处理策略是先从这些文档中提取出纯文本,然后再进行相关索引处理等。
一、从office中提取纯文本
从office文件中提取纯文本,可以使用POI(http://poi.apache.org/),最新版本为3.8。从office文件中提取纯文本方法很简单。只需要两行代码即可。
POITextExtractor extractor = ExtractorFactory.createExtractor(is);
String contents = extractor.getText();
第一行中传入的is参数为office文件的inputstream。这里不分word、excle还是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包为:pdfbox、fontbox、jempbox等,最好再加上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(); 即可获取到纯文本数据。