1、portal.properties里面用到的的配置:
路径:/portal-master/portal-impl/src/portal.properties
后台打印sql的配置:Hibernate.show_sql=true
页面session超时时间设置:session.timeout=300
只有powerUser用户才会自动创建 用户私有页:layout.user.private.layouts.power.user.required=true
只有powerUser用户才会自动创建 用户公开页:
layout.user.public.layouts.power.user.required=true
用户第一次登录时的相关配置:
关闭使用条款:terms.of.use.required=true
关闭密码提醒功能:users.reminder.queries.enabled=false
关闭首次登录强制修改密码功能:passwords.default.policy.change.required=false
2、在FreeMarker详情模板中获取值:
<#assign assetRenderer = curEntry.getAssetRenderer()>
<#assign docXml = saxReaderUtil.read(assetRenderer.getArticle().getContent()) />
<#assign description = docXml.valueOf("//dynamic-element[@name='title']/dynamic-content/text()") />
3、在Velocity模板中获取值:
#set($assetRenderer = $curEntry.getAssetRenderer())
#set($docXml = $saxReaderUtil.read($assetRenderer.getArticle().getContent()))
#set($description = $docXml.valueOf("//dynamic-element[@name='description']/dynamic-content/text()"))
4、获取Liferay当前页面的url:
PortalUtil.getCurrentURL(request);
5、中文乱码:在当前工程的build.gradle文件中添加如下信息
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
然后重新执行deploy
页面乱码:在页面增加如下代码:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page contentType="text/html;charset=utf-8"%>
6、liferay表
附件保存在以dlfile开头的表里面
portlet自定义属性保存在portletpreferences表里面
assetEntry里面可以查看有哪些属性
web内容文章存储在journalarticle里面
liferay模板都是存储在ddmtemplate表里面
7、liferay模板变量
FreeMarkerTemplateContextHelper.java
8、自定义字段
设置值和读取值
JournalArticle journalArticle = null;
journalArticle.getEcpandoBridge().setAttribute(“author”,”张三”);
journalArticle.getEcpandoBridge().getAttribute(“author”);
自定义字段在数据库里面存储的表:expandocolumn:栏目表、expandorow:行、expandotable:表、expandovalue:值
9、liferay中不需要的模板可以在控制面板->应用程序管理器中删掉
比如商务版块
卸载完后的效果:商务那一块就没有了
10、数据库里修改的在页面上没生效处理:
控制面板->服务器管理->清除数据库缓存
11、控制面板->组件里面可关闭不需要的portlet
12、查看liferay模块的版本
13、jsp的一些定制扩展
(1)、页面上找找相应的class或id标签的属性
(2)在liferay源码中搜索一下(idea的快捷键:crtil+shift+F)
(3)页面上没找到的话可以看看还有哪些js有引用
(4)如果这一块不需要的话可以去掉,
14、覆盖源码中的jsp页面
如点赞:
(1)新建一个mvc-portlet,可以删除不需要的生成文件
(2)在源码中找到对应的bnd文件
(3)修改新建的mvc-portlet中的bnd文件,也就是需要覆盖的源码是哪一个
(4)、把要覆盖的jsp复制出来放到对应的目录下面
(5)、测试一下
15、引入全局样式
(1)查找到源码中的扩展点
(2)引入全局css
String content = "<like href=\"/o/xxx/css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />";
@Component(immediate = true,service = DynamicInclude.class)
public class CssTopHeadDynamicInclude extends BaseDynamicInclude {
@Override
public void include(HttpServletRequest request, HttpServletResponse response, String key) throws IOException {
PrintWriter printWriter = response.getWriter();
String content = "<like href=\"/o/xxx/css/custom.css\" rel=\"stylesheet\" type=\"text/css\" />";
printWriter.println(content);
}
@Override
public void register(DynamicIncludeRegistry dynamicIncludeRegistry) { dynamicIncludeRegistry.register("/html/common/themes/top_head.jsp#pre");
}
}
16、定时任务
在自己的某个插件中建立如下类
/**
* 定时任务
*/
@Component(immediate = true, service = DdTestMessageListener.class)
public class DdTestMessageListener extends BaseMessageListener {
@Activate
protected void activate() {
Class<?> clazz = getClass();
String className = clazz.getName();
/** 每隔15秒钟执行一次 */
Trigger trigger = _triggerFactory.createTrigger(className, className, null, null,15, TimeUnit.SECOND);
SchedulerEntry schedulerEntry = new SchedulerEntryImpl(className, trigger);
_schedulerEngineHelper.register(this, schedulerEntry, DestinationNames.SCHEDULER_DISPATCH);
}
@Deactivate
protected void deactivate() {
_schedulerEngineHelper.unregister(this);
}
/**
* 定时任务执行的方法体
* @param message
* @throws Exception
*/
@Override
protected void doReceive(Message message) throws Exception {
System.out.println(new Date());
}
@Reference(target = ModuleServiceLifecycle.PORTAL_INITIALIZED, unbind = "-")
protected void setModuleServiceLifecycle(
ModuleServiceLifecycle moduleServiceLifecycle) {
}
@Reference(unbind = "-")
protected void setSchedulerEngineHelper(
SchedulerEngineHelper schedulerEngineHelper) {
_schedulerEngineHelper = schedulerEngineHelper;
}
private SchedulerEngineHelper _schedulerEngineHelper;
@Reference
private TriggerFactory _triggerFactory;
}
部署启动后看效果
17、覆盖全局Liferay语言包
(1)、找到源码中想要覆盖的语言配置
liferay-ce-portal-src-7.3.5-ga6\portal-impl\classes\content\Language_zh_CN.properties
(2)在自己的某个插件中建立如下类,在项目的language里面写对应的值
@Component(
property = { "language.id=zh_CN" },
service = ResourceBundle.class
)
public class MyCNResourceBundle extends ResourceBundle {
@Override
protected Object handleGetObject(String key) {
return _resourceBundle.getObject(key);
}
@Override
public Enumeration<String> getKeys() {
return _resourceBundle.getKeys();
}
private final ResourceBundle _resourceBundle = ResourceBundle.getBundle(
"content.Language_zh_CN", UTF8Control.INSTANCE);
}
(3)把需要覆盖的配置放在对应的文件中,如想把微件页改为portlet页
(4)部署后看效果,改成功了
18、覆盖指定模块语言包
Provide-Capability: \
liferay.resource.bundle;resource.bundle.base.name="content.Language",\
liferay.resource.bundle;resource.bundle.aggregate:String="(bundle.symbolic.name=com.huidian.zhanlve),(bundle.symbolic.name=com.liferay.portlet.configuration.css.web)";bundle.symbolic.name=com.liferay.portlet.configuration.css.web;resource.bundle.base.name="content.Language";service.ranking:Long="2";\
servlet.context.name=portlet-configuration-css-web
解析一下:
liferay.resource.bundle;resource.bundle.base.name="content.Language"声明模块的提供资源文件的内容content.Language
liferay.resource.bundle;resource.bundle.aggregate:String=...要汇集的资源文件名和排名
"(bundle.symbolic.name=com.huidian.zhanlve),(bundle.symbolic.name=com.liferay.portlet.configuration.css.web)":该服务从这两个包中汇集资源文件,前面的优先;
bundle.symbolic.name=com.liferay.portlet.configuration.css.web;resource.bundle.base.name="content.Language":覆盖com.liferay.portlet.configuration.css.web包的名为资源包content.Language
service.ranking:Long="2":资源包的服务排名为2
servlet.context.name=portlet-configuration-css-web:目标资源位于servlet中的上下文portlet-configuration-css-web


修改成功

19、覆盖源码中的MVCAction
比如在web内容发布提交时处理,先在源码中找到对应的action,可以用F12监听一下请求的路径对应的action



20、Hook事件-自定义变量
Portal.properties里面查看
application.shutdown.events:portal实例关闭
application.startup.events:Portal实例启动或创建时
global.shutdown.events:portal的main servlet关闭
global.startup.events:main servlet启动
layout.configuration.action.delete :页面删除
layout.configuration.action.update:页面初始化,更新
login.events.post:登录后事件.
login.events.pre:登录前事件
logout.events.post:退出后
logout.events.pre :退出前
servlet.service.events.post:处理完一个请求后.
servlet.service.events.pre:处理请求前
servlet.session.create.events:session创建事件
servlet.session.destroy.events:session销毁事件
@Component(
immediate = true, property = {"key=login.events.post"},
service = LifecycleAction.class
)
public class LandingRedirectAction implements LifecycleAction {
@Override
public void processLifecycleEvent(LifecycleEvent lifecycleEvent) throws ActionException {
HttpSession session = lifecycleEvent.getRequest().getSession();
session.setAttribute("LAST_PATH", new LastPath(StringPool.BLANK, "/group/zhanlve/index"));
}
}
@Component(
immediate = true, property = {"key=login.events.post"},
service = LifecycleAction.class
)
public class LandingRedirectAction implements LifecycleAction {
@Override
public void processLifecycleEvent(LifecycleEvent lifecycleEvent) throws ActionException {
HttpServletRequest request = lifecycleEvent.getRequest();
HttpSession session = request.getSession();
String useridStr = (String) session.getAttribute("j_username");
String friendlyUrL = StringPool.BLANK;
try {
long userId = GetterUtil.getLong(useridStr);
User user = UserLocalServiceUtil.getUser(userId);
//获取用户有哪些站点
List<Group> groups = user.getGroups();
if (!groups.isEmpty()) {
friendlyUrL = groups.get(0).getFriendlyURL();
}else {
//获取用户的组织机构
List<Organization> organizations = user.getOrganizations();
if (!organizations.isEmpty()) {
//取组织机构站点
Group group = organizations.get(0).getGroup();
if (null!=group) {
friendlyUrL = group.getFriendlyURL();
}
}
}
} catch (SystemException e) {
e.printStackTrace();
} catch (PortalException e) {
e.printStackTrace();
}
String redirect = ParamUtil.getString(request, "redirect");
if (Validator.isNotNull(redirect)) {
redirect = PortalUtil.escapeRedirect(redirect);
}
if (Validator.isNotNull(friendlyUrL)) {
redirect = "/group"+friendlyUrL;
LastPath lastPath = new LastPath(StringPool.BLANK, redirect);
session.setAttribute(WebKeys.LAST_PATH, lastPath);
}
}
}
21、自定义过滤器
@Component(
immediate = true,
property = {
//"before-filter=Auto Login Filter",
//"after-filter=SSO CAS Filter",
"dispatcher=FORWARD",
"dispatcher=REQUEST",
"servlet-context-name=",
"servlet-filter-name= Custom CAS LDAP Import Filter",
"url-pattern=/c/portal/login"
},
service = Filter.class)
public class CustomCASFilter extends BaseFilter {
@Override
public boolean isFilterEnabled(HttpServletRequest request, HttpServletResponse response){
//通过配置文件获取
//boolean enabled = GetterUtil.getBoolean(PropsUtil.get("custom.cas.ldap.import.enabled"));
return true;
}
@Override
protected void processFilter(HttpServletRequest request,HttpServletResponse response, FilterChain filterChain) throws Exception{
HttpSession session = request.getSession();
System.out.println("进入CustomCASFilter");
processFilter(CustomCASFilter.class.getName(), request, response, filterChain);
}
@Override
protected Log getLog() {
return _log;
}
private static final Log _log = LogFactoryUtil.getLog(
CustomCASFilter.class);
}
22、自动登录(验证,url上面带了userId就可以自动登录)
可以跟过滤器结合使用,过滤器过滤到对应请求地址,把信息写到session中,这里就可以从session中获取值了
@Component(
immediate = true,
service = AutoLogin.class
)
public class CustomLogin extends BaseAutoLogin {
@Override
protected String[] doLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
Long userId = ParamUtil.getLong(request,"userId");
if(Validator.isNotNull(userId)){
User user = UserLocalServiceUtil.fetchUser(userId);
return new String[]{ userId.toString(),user.getPassword(),String.valueOf(user.isPasswordEncrypted())};
}
return null;
}
}
提供回调地址
@Component(
immediate = true,
property = "path=/portal/sso/login",
service = StrutsAction.class
)
public class LoginAction implements StrutsAction{
@Override
public String execute(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
String token = ParamUtil.getString(httpServletRequest,"token");
System.out.println("token:"+token);
if(Validator.isNotNull(token)){
//在这里调用方法,处理用户信息,比如自动创建或调用用户信息等
Long userId = GetterUtil.getLong(token);
HttpSession session = httpServletRequest.getSession();
session.setAttribute("CUSTOM_LOGIN_USER_ERROR","test error");
session.setAttribute("CUSTOM_LOGIN_USER_ID",userId);
}
httpServletResponse.sendRedirect("/web/guest");
return null;
}
}
实际访问时前面要加一个c
中文不能识别
23、liferay在报错或者找不到路径时,全部跳转到原有的error页面
bundles/tomcat-8.0.32/webapps/ROOT/errors/code.jsp。项目中需要自定404页面:首先,在bundles/tomcat-8.0.32/webapps/ROOT/errors/ 文件夹中创建自定义的404.jsp页面(如果想在该页面中显示一些系统信息,可以参照code.jsp的写法);然后在配置文件中配置该404页面:
layout.show.http.status=true
layout.friendly.url.page.not.found=/errors/404.jsp