zoukankan      html  css  js  c++  java
  • liferay7.0开发的二三坑

    参考:https://blog.csdn.net/u012551585/article/details/62261352?locationNum=7&fps=1

    liferay7.0的官方文档并不稳定,一直在更新完善,比如Liferay7.0 通过JPM安装Blade Cli 时[ZipFile.open] error in opening zip file 这篇,现在官网已经更新,没有这个问题了,希望新版本早日稳定,以下是我开发时遇到的一些问题:

     

    问题一:Portlet页面中使用AJAX请求Portlet控制类中serveResource时,resourceRequest得到的AJAX请求参数为NULL ?

    问题二:Liferay不同页面拥有不同theme时,切换页面时,上一个页面的theme会Cache下来

    问题三:Liferay自定义字段操作

    问题四:Liferay自定义JSON服务接口

    问题五:在Liferay API基础上自定义 数据库查询

    问题六:Liferay用户具有哪些状态,比如停用、激活等

    问题七:Liferay添加用户时,用户screenname不允许为全数字

    问题八: Liferay自定义登录

    问题九:Liferay自定义ERROR404页面

    问题十:Blade安装问题,官网提供的blade依赖的Java Package Manager 地址无法访问(截止2017.4.20日)

    问题十一:Liferay 自动登录

    问题十二:MVCPortlet中得到所在页面的请求参数

    问题十三:Liferay7.0中任务调度定时任务

    问题十四:Liferay7.0中上下文提供者

     

    问题一:Portlet页面中使用AJAX请求Portlet控制类中serveResource时,resourceRequest得到的AJAX请求参数为NULL ?

           这个问题主要是LIferay默认情况下要求为参数加上namespace才行,这个有点坑,表单那块如果使用aui是没有这个问题的,如果使用原生表单项的话,也会遇到相同的问题,后台接收不到传的参数;所以只需为我们的请求项加上namespace就行了:

    1.  
      $.post('<%=resourceURL%>',
    2.  
      {"<portlet:namespace />action":"role",
    3.  
      "<portlet:namespace />plid":plidPageId,
    4.  
      "<portlet:namespace />roleId":roleId
    5.  
      },
    6.  
      function(data){
    7.  
      });

    问题二:Liferay不同页面拥有不同theme时,切换页面时,上一个页面的theme会Cache下来

             这个问题主要它的缓存机制有关,liferay提供了相关的Cache禁用配置,在portal-ext.properties添加以下配置:

    1.  
      #禁止缓存
    2.  
      theme.css.fast.load=false
    3.  
      theme.css.fast.load.check.request.parameter=true
    4.  
      theme.images.fast.load=false
    5.  
      theme.images.fast.load.check.request.parameter=true
    6.  
       
    7.  
      javascript.fast.load=false
    8.  
      javascript.log.enabled=false
    9.  
       
    10.  
      layout.template.cache.enabled=false
    11.  
       
    12.  
      browser.launcher.url=
    13.  
       
    14.  
      combo.check.timestamp=true
    15.  
       
    16.  
      freemarker.engine.cache.storage=soft:1
    17.  
      freemarker.engine.resource.modification.check.interval=0
    18.  
       
    19.  
      minifier.enabled=false
    20.  
       
    21.  
      openoffice.cache.enabled=false
    22.  
       
    23.  
      velocity.engine.resource.modification.check.interval=0
    24.  
       
    25.  
      com.liferay.portal.servlet.filters.cache.CacheFilter=false
    26.  
      com.liferay.portal.servlet.filters.etag.ETagFilter=false
    27.  
      com.liferay.portal.servlet.filters.header.HeaderFilter=false

         

             portal-ext.properties配置相关的属性值,在https://docs.liferay.com/ce/portal/7.0-latest/propertiesdoc/portal.properties.html可以查看全部的配置信息

    问题三:Liferay自定义字段操作

             某些情况下,Liferay自定义的数据库字段并不能满足要求,Liferay允许在已有字段的基础上添加自定义字段,Liferay后台提供了添加自定义字段的界面操作(控制面板>配置>自定义字段),自定义字段的数据存储结构和wordpress自定义的存储字段一样,并没有在修改原有表,而是都存储在expando开头的数据表中,https://docs.liferay.com/portal/7.0/javadocs/portal-kernel/com/liferay/expando/kernel/service/package-frame.html提供了相关的API,下面是一个取自定义值得例子:

    1.  
      long companyId=PortalUtil.getCompanyId(renderRequest);
    2.  
      try {
    3.  
      long testUserId=UserLocalServiceUtil.getUserByScreenName(companyId, "test").getPrimaryKey();
    4.  
      System.out.println(testUserId);
    5.  
      String testvalue=ExpandoValueLocalServiceUtil.getData(companyId, User.class.getName(),
    6.  
      "CUSTOM_FIELDS", "customword",
    7.  
      testUserId, "test");
    8.  
      System.out.println(testvalue);
    9.  
      renderRequest.setAttribute("customword", testvalue);
    10.  
      } catch (PortalException e) {
    11.  
      // TODO Auto-generated catch block
    12.  
      e.printStackTrace();
    13.  
      }

    问题四:Liferay自定义JSON服务接口

            Liferay提供了两种工具新建Service模块,Eclipse 和Blade 方式创建,需要注意的就是创建以后远程的调用路径问题,可以参考官网给出的实例

           

        另外,Liferay支持修改官网提供的接口,通过http://localhost:8080/api/jsons查看Liferay提供的原有接口,可参照官网https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/customizing-liferay-services-service-wrappers覆盖原有借口,但要注意此模块只能覆盖原接口,不能新建接口,新建接口还需要使用上述方法。

    问题五:在Liferay API基础上自定义 数据库查询

                 Liferay API提供了大量的操作,但某些情况下它提供的不是太灵活,需要我们自定义,API提供了这方面的支持,例如:

     

    1.  
      DynamicQuery guestbookQuery = DynamicQueryFactoryUtil.forClass(Guestbook.class)
    2.  
      .add(RestrictionsFactoryUtil.eq("name", guestbookName))
    3.  
      .setProjection(ProjectionFactoryUtil.property("guestbookId"));
    4.  
       
    5.  
      Order order = OrderFactoryUtil.desc("modifiedDate");
    6.  
       
    7.  
      DynamicQuery entryQuery = DynamicQueryFactoryUtil.forClass(Entry.class)
    8.  
      .add(RestrictionsFactoryUtil.eq("name", entryName))
    9.  
      .add(PropertyFactoryUtil.forName("guestbookId").in(guestbookQuery))
    10.  
      .addOrder(order);
    11.  
       
    12.  
      List<Event> entries = EventLocalServiceUtil.dynamicQuery(entryQuery);

    问题六:Liferay用户具有哪些状态,比如停用、激活等

               

    1.  
      public static final int STATUS_ANY = -1;
    2.  
      public static final int STATUS_APPROVED = 0;
    3.  
      public static final int STATUS_DENIED = 4;
    4.  
      public static final int STATUS_DRAFT = 2;
    5.  
      public static final int STATUS_DRAFT_FROM_APPROVED = 9;
    6.  
      public static final int STATUS_EXPIRED = 3;
    7.  
      public static final int STATUS_INACTIVE = 5;
    8.  
      public static final int STATUS_INCOMPLETE = 6;
    9.  
      public static final int STATUS_PENDING = 1;
    10.  
      public static final int STATUS_SCHEDULED = 7;

              可以去http://note.youdao.com/noteshare?id=0018de9bef6459ea3aab2c6f8f07d4ec查看用户所用状态。

    问题七:Liferay添加用户时,用户screenname不允许为全数字

             当我们自定义注册时,会发现liferay默认情况下screenname字段不允许为全数字:

     

    1.  
      //添加用户
    2.  
      try {
    3.  
      User u=UserLocalServiceUtil.addUserWithWorkflow(currentuserId, companyId, false, password, password,
    4.  
      false, screenname, email, 0L,
    5.  
      phone, new Locale("zh_CN"), username, username,
    6.  
      username, 0L, 0L, "男".equals(sex)?true:false,
    7.  
      month, day, year, message,
    8.  
      null, null, roles, null,
    9.  
      false, ServiceContextFactory.getInstance(resourceRequest));
    10.  
      UserLocalServiceUtil.updateStatus(u.getUserId(), WorkflowConstants.STATUS_INACTIVE,ServiceContextFactory.getInstance(resourceRequest));
    11.  
      } catch (PortalException e) {
    12.  
       
    13.  
      e.printStackTrace();
    14.  
      }


            查看数据库可知该字段为varchar,应该支持全数字,查看配置文件,果然是可配置项:

     

    1.  
      users.screen.name.allow.numeric=true
    2.  
       

    问题八: Liferay自定义登录

              Liferay默认提供了三种登录方式:

     

    1.  
      public static final String AUTH_TYPE_EA = "emailAddress";
    2.  
       
    3.  
      public static final String AUTH_TYPE_ID = "userId";
    4.  
       
    5.  
      public static final String AUTH_TYPE_SN = "screenName";

           

            自定义登录代码示例http://download.csdn.net/detail/u012551585/9825444

            自定义好登录页面后怎样替换默认的登录页面呢,需要在添加配置项:

     

    1.  
      #登录页面
    2.  
      auth.login.url=/zh_CN/web/guest/customlogin
    3.  
       

    问题九:Liferay自定义ERROR404页面

           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页面:

     

    1.  
      layout.show.http.status=true
    2.  
      layout.friendly.url.page.not.found=/errors/404.jsp
    3.  
       


    问题十:Blade安装问题,官网提供的blade依赖的Java Package Manager 地址无法访问(截止2017.4.20日),这个估计官网后续会更新,下面给出一个解决方案:

             Linux下直接运行下面命令:

    1.  
      curl -sL https://github.com/jpm4j/jpm4j.installers/raw/master/dist/biz.aQute.jpm.run.jar > tmp.jar &&
    2.  
      JPM_BIN_DIR=`java -jar tmp.jar -g init | grep -e "Bin[ ]*dir" | awk '{print $3}'` &&
    3.  
      rm -f tmp.jar &&
    4.  
      ${JPM_BIN_DIR}/jpm install -f https://releases.liferay.com/tools/blade-cli/latest/blade.jar &&
    5.  
      echo "blade installed successfully into ${JPM_BIN_DIR}/blade"
    6.  
       

            Windows下:

          https://github.com/jpm4j/jpm4j.installers/blob/master/dist/jpm-setup.exe

    问题十一:Liferay 自动登录

             某些访问写略下,我们可能会要求liferay自动登录,官方教程:https://dev.liferay.com/zh/develop/tutorials/-/knowledge_base/7-0/auto-login

             首先,在任意一个module project中新建一个class继承AutoLogin,最主要的就是实现它的login方法的返回值,要求是一个String数组,数组的第一个值为你要登录的用户ID,第二个值为密码,第三个值为密码是否加密("true"或"false"),代码示例如下:

     

    1.  
      package com.zonebase.liferaylogin.portlet;
    2.  
       
    3.  
      import javax.servlet.http.HttpServletRequest;
    4.  
      import javax.servlet.http.HttpServletResponse;
    5.  
       
    6.  
      import org.osgi.service.component.annotations.Component;
    7.  
       
    8.  
      import com.liferay.portal.kernel.model.User;
    9.  
      import com.liferay.portal.kernel.security.auto.login.AutoLogin;
    10.  
      import com.liferay.portal.kernel.security.auto.login.AutoLoginException;
    11.  
      import com.liferay.portal.kernel.service.UserLocalServiceUtil;
    12.  
       
    13.  
      @Component(immediate = true)
    14.  
      public class CustomAutoLogin implements AutoLogin{
    15.  
      //该方法可以不管返回null
    16.  
      @Override
    17.  
      public String[] handleException(HttpServletRequest request, HttpServletResponse response, Exception e)
    18.  
      throws AutoLoginException {
    19.  
      // TODO Auto-generated method stub
    20.  
      return null;
    21.  
      }
    22.  
      //主要是该方法的返回值
    23.  
      @Override
    24.  
      public String[] login(HttpServletRequest request, HttpServletResponse response) throws AutoLoginException {
    25.  
      //默认登录之后跳转到主页面,也可以通过该属性进行设置
    26.  
      request.setAttribute("AutoLogin.AUTO_LOGIN_REDIRECT", "/show1");
    27.  
       
    28.  
      String userId=request.getParameter("userId");
    29.  
      if(userId!=null&&userId!=""){
    30.  
      User user=UserLocalServiceUtil.fetchUser(Long.parseLong(userId));
    31.  
      return new String[] { userId,user.getPassword(),String.valueOf(user.getPasswordEncrypted())};
    32.  
      }
    33.  
      return null;
    34.  
      }
    35.  
      }


                接下来,重要的是在配置文件中配置该自动登录的地址:

     

    1.  
      auto.login.hooks=com.zonebase.liferaylogin.portlet.CustomAutoLogin
    2.  
       


    问题十二:MVCPortlet中得到所在页面的请求参数

            某些情况下,在portlet中可能要得到该请求页面的请求参数,只需获得HttpServletRequest,代码如下:

     

    1.  
      public class HomepagePortlet extends MVCPortlet {
    2.  
      @Override
    3.  
      public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
    4.  
      throws IOException, PortletException {
    5.  
      HttpServletRequest request = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
    6.  
      HttpServletResponse response=PortalUtil.getHttpServletResponse(renderResponse);
    7.  
      String test=request.getParameter("test");
    8.  
      .....
    9.  
      .....
    10.  
      }
    11.  
      }
    12.  
       

    问题十三:Liferay7.0中任务调度定时任务

    1.  
      package test.scheduler.portlet;
    2.  
      import org.osgi.service.component.annotations.Activate;
    3.  
      import org.osgi.service.component.annotations.Component;
    4.  
      import org.osgi.service.component.annotations.Deactivate;
    5.  
      import org.osgi.service.component.annotations.Modified;
    6.  
      import org.osgi.service.component.annotations.Reference;
    7.  
       
    8.  
      import com.liferay.portal.kernel.messaging.BaseSchedulerEntryMessageListener;
    9.  
      import com.liferay.portal.kernel.messaging.DestinationNames;
    10.  
      import com.liferay.portal.kernel.messaging.Message;
    11.  
      import com.liferay.portal.kernel.module.framework.ModuleServiceLifecycle;
    12.  
      import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
    13.  
      import com.liferay.portal.kernel.scheduler.TimeUnit;
    14.  
      import com.liferay.portal.kernel.scheduler.TriggerFactory;
    15.  
      import com.liferay.portal.kernel.scheduler.TriggerFactoryUtil;
    16.  
      /**
    17.  
      * 任务调度DEMO
    18.  
      * @author zonebase@163.com
    19.  
      */
    20.  
      @Component(immediate = true, service = TestSchedulerEntryMessageListener.class)
    21.  
      public class TestSchedulerEntryMessageListener extends BaseSchedulerEntryMessageListener {
    22.  
      @Reference(target = ModuleServiceLifecycle.PORTAL_INITIALIZED, unbind = "-")
    23.  
      private volatile ModuleServiceLifecycle _moduleServiceLifecycle;
    24.  
      @Reference(unbind = "-")
    25.  
      private volatile SchedulerEngineHelper _schedulerEngineHelper;
    26.  
      @Reference(unbind = "-")
    27.  
      private volatile TriggerFactory _triggerFactory;
    28.  
      @Activate
    29.  
      @Modified
    30.  
      protected void activate() {
    31.  
      //触发器 定义
    32.  
      schedulerEntryImpl.setTrigger(
    33.  
      TriggerFactoryUtil.createTrigger(
    34.  
      getEventListenerClass(), getEventListenerClass(), 60,
    35.  
      TimeUnit.MINUTE));
    36.  
      _schedulerEngineHelper.register(
    37.  
      this, schedulerEntryImpl, DestinationNames.SCHEDULER_DISPATCH);
    38.  
      }
    39.  
       
    40.  
      @Deactivate
    41.  
      protected void deactivate() {
    42.  
      _schedulerEngineHelper.unregister(this);
    43.  
      }
    44.  
      @Override
    45.  
      protected void doReceive(Message message) throws Exception {
    46.  
      //任务
    47.  
      System.out.println("轮训执行。。。。。。。。。。。。");
    48.  
      }
    49.  
       
    50.  
      }
    51.  
       


    问题十四:上下文提供者

           某些情况下,我们需要自定义一些像themeDisplay 的上下文对象来储存信息,相关的文档请看https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/context-contributors

       示例如下:

    1.  
      package com.zonebase.testcontext.context.contributor;
    2.  
       
    3.  
      import com.liferay.portal.kernel.template.TemplateContextContributor;
    4.  
       
    5.  
      import java.util.Map;
    6.  
       
    7.  
      import javax.servlet.http.HttpServletRequest;
    8.  
       
    9.  
      import org.osgi.service.component.annotations.Component;
    10.  
       
    11.  
      /**
    12.  
      * 上下文提供者DEMO
    13.  
      * @author zonebase@163.com
    14.  
      */
    15.  
      @Component(
    16.  
      immediate = true,
    17.  
      property = {"type=" + TemplateContextContributor.TYPE_THEME},
    18.  
      service = TemplateContextContributor.class
    19.  
      )
    20.  
      public class TestContextContributorTemplateContextContributor
    21.  
      implements TemplateContextContributor {
    22.  
       
    23.  
      @Override
    24.  
      public void prepare(
    25.  
      Map<String, Object> contextObjects, HttpServletRequest request) {
    26.  
      contextObjects.put("customObject", "Hello World.");
    27.  
      }
    28.  
       
    29.  
      }

    文末彩蛋:Liferay7.0官方实例库https://github.com/liferay/liferay-blade-samples/tree/master/maven

  • 相关阅读:
    [HAOI2008] 硬币购物
    [HNOI2002] Kathy 函数
    [SCOI2009] windy数
    圆方树总结
    ABOUT ME && 友链
    逝念偶拾
    文化课日常
    记一些欢愉
    浅谈
    洛谷 4823 [TJOI2013]拯救小矮人
  • 原文地址:https://www.cnblogs.com/show58/p/13713060.html
Copyright © 2011-2022 走看看