要为首次首次明确加载页面创建显式会话 [英] To create a session explicitly for first the first time page loads in Grails

查看:49
本文介绍了要为首次首次明确加载页面创建显式会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

页面加载后,它会渲染大量数据并在视图上显示会降低性能的某种方式.我想限制它,仅在应用过滤器时才加载数据.我需要一种会话变量可以在第一次登录时存储值的方法,并且不应在该第一次会话中加载任何数据,即当任何用户首次使用其登录名首次加载它时.类似于控制器类中的以下内容:

  if(session.dtstartDate&&session.dtstartDate!=''){SimpleDateFormat nsdf =新的SimpleDateFormat('yyyy-MM-dd')日期startDateValue = nsdf.parse(session.dtstartDate.substring(0,session.dtstartDate.lastIndexOf("T")))eq("startDate",startDateValue)//如果应用了任何过滤器}别的{如果这是第一次会话,则开始日期应为null->需要一段代码在这里替换} 

解决方案

我不确定也许我仍然没有得到您试图正确询问的内容,我想我应该尝试回答您的问题,以了解您对问题的理解.是.

如果我们使用此基本过滤器并添加一些东西,我们也许可以使用更好的方法来实现您的期望?我不确定startDate实际代表什么,但是如果我们基于它是基于用户是否首次按下控制器,或者答案不是这样的话,则可以替换startDate的逻辑,如果它具有其他意义:

,因此添加了一些哈希映射数组集到您在用户点击控制器/操作时调用该操作之前被调用的过滤器:

在您的conf/MyFiters.groovy

  class MyFilters {静态最终Set< HashMap< String [],String []>>userControl =([:]为Set).asSynchronized()//控制器是controllerName,动作是actionNamedef过滤器= {MyLogger(){之前= {如果(verifyClientMaster(session.id as String,controllerName)== false){clientMaster.add(session.id为String:controllerName)//现在您在这里有了一个新用户//一些gsp的会话值或加载某些内容//根据}别的{//用户在执行其他操作或设置其他操作之前已经点击它}}}}}布尔型verifyClientMaster(String sessionId,String controller){//迭代发现的布尔值=否userControl.each {k,v->if(k == sessionId&&v; =控制器){找到=真}}} 

类似这样的事情,您会知道用户是否按下了控制器..请记住,会话是针对每个用户的.因此新用户拥有新的会话实体.

希望这对您有所帮助,不会偏离正轨.

E2A

考虑到这一点,您确实走了这条路,那么您需要跟踪会话何时过期,并从clientMaster中删除用户..

甚至比这任何一个都更简单的是,如果您加载的内容可以基于gsp,则使用gsp内置的情报...(未测试过任何情报)

 < g:if test ="$ {!session." $ {controllerName}}">< g:set var ="$ {controllerName}" value ="$ {controllerName}" scope ="session"/>< g:render template ="firstTimeHitter"/></g:if>< g:else>< g:render template ="secondTimeHitter"/></g:else> 

或者只是您的控制器进行检查和设置,然后渲染不同的东西或设置gsp拾取的东西.

  def myController {def doSomething(){布尔值firstTime =假if(!session."$ {controllerName}"){//第一次渲染或设置firsTimefirstTime = true会话."$ {controllerName}" = controllerName//或startDate//渲染视图:"firstTime,模型:[firstTime:firstTime,params:params]} 别的{//渲染视图:"firstTime,模型:[firstTime:firstTime,params:params]}//如果上面没有渲染:渲染视图:'doSomething,模型:[firstTime:firstTime,params:params]//现在在doSomething gsp中,您需要寻找firstTime:} 

做点事情:

 < g:if test ="$ {firstTime.toString().equals('true')}">< g:render template ="firstTimeHitter"/></g:if>< g:else>< g:render template ="secondTimeHitter"/></g:else> 

可能性是无止境的,区别在于使用一个过滤器就可以满足所有需求,即,它正在检查每个控制器,因为每个用户都击中了它.在controller和gsp解决方案中,您必须在需要的地方声明它.您可以有一个抽象控制器,其他控制器可以扩展该抽象控制器,以作为调用更高级别的类来重复进行该检查,而不管它们的重复性比简单的一次性过滤器要重复得多...

提供其他替代方案的最终编辑将是:

 最终Set< Session>jsessions =([]为Set).asSynchronized()jsessions.add('controller1')jsessions.add('controller2')jsessions.add('controller3')jsessions.add(controllerName)println"=== $ {jsessions}"如果(jsessions.contains(controllerName)){println-我们在会话集中定义了$ {controllerName} .... jsessions"}ArrayList jsessions2 = []jsessions2.add(controllerName)session.jsessions2 = jsessions2//在每次通话时重复此操作ArrayList jsessionsret = session.jsessions2jsessionsret.add('controller1')jsessionsret.add('controller2')jsessionsret.add('controller3')session.jsessions2 = jsessionsret如果(jsessions2.contains(controllerName)){println-我们在会话集中定义了$ {controllerName} .... jsessionsret"}println"222 --- $ {jsessions2}" 

以上部分是两种不同的实现方式:首先使用全局会话集,如果您不关心控制器是否被usera userb击中,则可以使用它,因此,如果usera击中了userb,也将其视为击中了它...这是jsessions.

最下面的jsessions2是尝试将单个会话密钥转换为ArrayList.因此,而不是为每个用户会话的每次控制器调用存储大量单个对象,即会话"$ {controllerName}".您可以为每个用户分配一个单一的会话密钥,然后将他们击中的每个控制器附加到..然后检查他们是否具有该控制器

As soon as a page loads, it renders a lot of data and shows on the view which sort of slows down the performance. I want to restrict this and load the data only when a filter is applied . I need a way in which a session variable can store the value on the 1st login and no data should be loaded in that 1st session i.e. when any user loads it for the very first time using his login. something like the below in the controller class:

if(session.dtstartDate && session.dtstartDate != '')
{
SimpleDateFormat nsdf = new SimpleDateFormat('yyyy-MM-dd')
Date startDateValue = nsdf.parse(session.dtstartDate.substring(0, session.dtstartDate.lastIndexOf("T")))
    eq("startDate", startDateValue)//if any filter is applied
}
else{
    if this is the 1st session the startdate should be null --> need a piece of code to be replaced here
}

I am unsure maybe I still have not got what you have tried to ask properly, I thought I should try to answer your question to how I understood your problem to be.

If we take this basic filter and add some stuff to it we may be able to get to what you wish to do using a better method ? I am unsure what startDate is actually representing but if we base it on if a user has hit a controller for the first time or not the answer would be something like this, you could replace the logic to startDate if it has other significance:

so adding some hashmap arrayset to your filter that gets called before the action is called when user clicks the controller/action:

in your conf/MyFiters.groovy

class MyFilters {
  static final Set<HashMap<String[],String[]>> userControl = 
([:] as     Set).asSynchronized()
//where controller is  controllerName and  action is actionName
        def filters = {
            MyLogger() {
                before = {
                  if (verifyClientMaster(session.id as String ,controllerName)==false) { 
                    clientMaster.add(session.id as String:controllerName)
                     // now here you have a new user so set 
                     // some session value for gsp or load something 
                     //according
             }else{
              // user has hit it before do something else or set something else
              }
                }
            }
         }
      }


  Boolean verifyClientMaster(String sessionId,String controller) {
     // iterate 
     boolean found = false
     userControl.each { k,v -> if (k == sessionId && v == controller) {
     found = true
     }
     }
    }

something like this and you know if the user has hit the controller or not.. remember the session is per user. so a new user has a new session entity.

Hope it is of help and not off track..

E2A

Thinking about it you do go down this route then you would need to keep track of when session expires and to remove the user from clientMaster.. take a look at this project if you did go down this route.. personally I would even do it simpler than this... on a rethink...

  class MyFilters {
        def filters = {
            MyLogger() {
                before = {
                  if (!sessions."${controllerName}") { 
                       sessions."${controllerName}"="${controllerName}"
                     // now here you have a new user so set 
                     // some session value for gsp or load something 
                     //according
                  }else{
                     // user has hit it before do something else or set something else
                   }
                }
            }
         }
      }

and even simple than any of this would be to use the intelligence built into a gsp if what you load can be based on it... (not tested any of it ha)

<g:if test="${!session."${controllerName}"}">
         <g:set var="${controllerName}" value="${controllerName}" scope="session" />

         <g:render template="firstTimeHitter"/>
</g:if>
<g:else>
         <g:render template="secondTimeHitter"/>                
</g:else>

or just your controller that checks and sets that and either renders something different or sets something gsp picks up on..

def myController {
  def doSomething() { 
    boolean firstTime = false
    if (!session."${controllerName}") { 
     // first time either render or set firsTime
     firstTime = true
       session."${controllerName}" = controllerName // or startDate
     // render view: 'firstTime, model: [firstTime:firstTime, params:params]

  } else{ 
        // render view: 'firstTime, model: [firstTime:firstTime, params:params]
  }
  // if no render above:
  render view: 'doSomething, model: [firstTime:firstTime, params:params]
  // now in doSomething gsp you look for firstTime:

}

do someThing:

<g:if test="${firstTime.toString().equals('true')}">
  <g:render template="firstTimeHitter"/>
</g:if>
<g:else>
 <g:render template="secondTimeHitter"/>
</g:else>

The possibilities are endless, the differences being with a filter its a one fits all, i.e. it is checking every controller as it is hit by each user. In controller and gsp solution you have to declare it where needed. You could have an abstract controller that other controllers extend to repeat that check as a higher class that gets called to verify, regardless their all a lot more repetitive than a simple one off filter...

Final Edit to give other other alternatives would be:

 final Set<Session> jsessions = ([] as Set).asSynchronized()
     jsessions.add('controller1')
     jsessions.add('controller2')
     jsessions.add('controller3')
     jsessions.add(controllerName)

     println "=== ${jsessions}"
     if (jsessions.contains(controllerName)) {
         println "--- We have ${controllerName} defined in our session set.... jsessions"
     }

     ArrayList jsessions2 = []
     jsessions2.add(controllerName)
     session.jsessions2 = jsessions2

     //repeat this on every call 
     ArrayList jsessionsret = session.jsessions2
     jsessionsret.add('controller1')

     jsessionsret.add('controller2')
     jsessionsret.add('controller3')

     session.jsessions2 = jsessionsret

     if (jsessions2.contains(controllerName)) {
         println "--- We have ${controllerName} defined in our session set.... jsessionsret"
     }
      println "222 --- ${jsessions2}"

This segment above are two different implementations of using first a session set that is global and could be used if you do not care if the controller is hit by usera userb etc so if usera hits it userb would also be considered as hitting it.. This is jsessions.

The bottom jsessions2 is an attempt to turn a single session key into an ArrayList. So rather than storing lots of single object i.e. session."${controllerName}" per call of a controller per user session. You could have 1 single session key per user that you append each controller they hit to.. and you then check to see if they have that controller

这篇关于要为首次首次明确加载页面创建显式会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆