JSF ViewScope bean,viewParam,ajax请求使用NULL更新MB属性 [英] JSF ViewScope bean, viewParam, ajax request update the MB attribute with NULL

查看:93
本文介绍了JSF ViewScope bean,viewParam,ajax请求使用NULL更新MB属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在

 <context-param>
        <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
        <param-value>true</param-value>
 </context-param>

在这里一切都按预期工作.

Here everything is working as expected.

现在我正在尝试将其更新为与Mojarra 2.3.9.payara-p3一起运行的Payara 5.1.9.3.

Now I`m trying to update it to Payara 5.1.9.3 that is running with Mojarra 2.3.9.payara-p3.

我现在面临的问题是,如果在创建该bean时使用参数f:viewParam设置参数的 ViewScope bean被用来触发ajax请求,则viewParams将会丢失(正常),并且模型使用NULL值进行更新.

The problem that I'm facing now is that if a ViewScope bean that has parameters set with f:viewParam on the creation of the bean is used to fire ajax requests the viewParams are lost (normal) and the model IS updated with NULL values.

所以最初viewParams可以正常工作,从GET中获取值并相应地设置模型.当在UPDATE_MODEL_VALUES PHASE中触发第一个ajax请求时,bean属性值设置为旧值(可以) ,但同样在阶段4中,在第二个ajax请求中,属性值也更新为NULL.

So initially the viewParams works ok, the values are taken from the GET and the model is set accordingly.When the first ajax request is fired in the UPDATE_MODEL_VALUES PHASE the bean attribute value is set with the old value (which is OK), but on the second ajax request also in PHASE 4 the attribute value is updated with NULL.

我知道有关此主题的文章很多(f:viewParams在ajax请求中丢失),但我不清楚的是:

I know that there are a lot of posts on this topic (f:viewParams are lost on ajax requests), but what is not clear to me is:

为什么如果我禁用javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL指令,一切正常,如果我不再启用它了?

PS.与Payara 4.1.2.174和Mojarra 2.2.14一起工作

PS. with Payara 4.1.2.174 and Mojarra 2.2.14 is working

更新:

在这里,我们可以看到counter.xhtml

here we have the view of counter.xhtml

<ui:composition template="../layouts/user.xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:p="http://primefaces.org/ui"
  xmlns:sec="http://www.springframework.org/security/tags">

<f:metadata>
    <f:viewParam name="id" value="#{counterMB.id}"/>        
</f:metadata>

<ui:param name="currentMB" value="#{counterMB}"/>   
<ui:define name="title">Counter </ui:define>

<h:form id="myForm">
    Id is <h:outputText value="#{counterMB.id}" id="outputTxt"/>

    <p:commandLink 
            action="#{counterMB.incrementCounter()}"
            value="Increment"
            update="outputTxt"
    />

    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</h:form>   

和bean:

@Named
@Scope("view")
public class CounterMB extends GenericMB implements Serializable{

    private static final long serialVersionUID = 1L;


    private Integer id;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        System.out.println("Setting the id with:"+id);
        this.id = id;
    }



    public void incrementCounter() {        

        id = id +1;

        // do something with id
        System.out.println("Id is="+Integer.toString(id));      
    }
}  

和一些日志:

http://localhost:8080/myapp/counter.xhtml?id=4

(LifecycleListener.java:22) - START PHASE RESTORE_VIEW 1
(LifecycleListener.java:26) - END PHASE RESTORE_VIEW 1
(LifecycleListener.java:22) - START PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:26) - END PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:22) - START PHASE PROCESS_VALIDATIONS 3
(LifecycleListener.java:26) - END PHASE PROCESS_VALIDATIONS 3
(LifecycleListener.java:22) - START PHASE UPDATE_MODEL_VALUES 4

2019-10-24T13:43:52.573+0000|Info: Setting the id with:4
(LifecycleListener.java:26) - END PHASE UPDATE_MODEL_VALUES 4
(LifecycleListener.java:22) - START PHASE INVOKE_APPLICATION 5
(LifecycleListener.java:26) - END PHASE INVOKE_APPLICATION 5
(LifecycleListener.java:22) - START PHASE RENDER_RESPONSE 6
(LifecycleListener.java:26) - END PHASE RENDER_RESPONSE 6


//click on increment 1st time
(LifecycleListener.java:22) - START PHASE RESTORE_VIEW 1
(LifecycleListener.java:26) - END PHASE RESTORE_VIEW 1
(LifecycleListener.java:22) - START PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:26) - END PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:22) - START PHASE PROCESS_VALIDATIONS 3
(LifecycleListener.java:26) - END PHASE PROCESS_VALIDATIONS 3
(LifecycleListener.java:22) - START PHASE UPDATE_MODEL_VALUES 4
2019-10-24T13:44:07.013+0000|Info: Setting the id with:4
(LifecycleListener.java:26) - END PHASE UPDATE_MODEL_VALUES 4
(LifecycleListener.java:22) - START PHASE INVOKE_APPLICATION 5
2019-10-24T13:44:07.014+0000|Info: Id is=5
(LifecycleListener.java:26) - END PHASE INVOKE_APPLICATION 5
(LifecycleListener.java:22) - START PHASE RENDER_RESPONSE 6
(LifecycleListener.java:26) - END PHASE RENDER_RESPONSE 6


// click on icrement the second time
(LifecycleListener.java:22) - START PHASE RESTORE_VIEW 1
(LifecycleListener.java:26) - END PHASE RESTORE_VIEW 1
(LifecycleListener.java:22) - START PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:26) - END PHASE APPLY_REQUEST_VALUES 2
(LifecycleListener.java:22) - START PHASE PROCESS_VALIDATIONS 3
LifecycleListener.java:26) - END PHASE PROCESS_VALIDATIONS 3
(LifecycleListener.java:22) - START PHASE UPDATE_MODEL_VALUES 4
2019-10-24T13:44:12.548+0000|Info: Setting the id with:null
(LifecycleListener.java:26) - END PHASE UPDATE_MODEL_VALUES 4
(LifecycleListener.java:22) - START PHASE INVOKE_APPLICATION 5
2019-10-24T13:44:12.549+0000|Warning: #{counterMB.incrementCounter()}: java.lang.NullPointerException
javax.faces.FacesException: #{counterMB.incrementCounter()}: java.lang.NullPointerException
    at com.sun.faces.application.ActionListenerImpl.getNavigationOutcome(ActionListenerImpl.java:96)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:71)
    at org.springframework.faces.webflow.FlowActionListener.processAction(FlowActionListener.java:71)
    at org.springframework.faces.model.SelectionTrackingActionListener.processAction(SelectionTrackingActionListener.java:64)
    at org.primefaces.application.DialogActionListener.processAction(DialogActionListener.java:54)
    at javax.faces.component.UICommand.broadcast(UICommand.java:222)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:847)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1395)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:58)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:76)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:177)
    at javax.faces.webapp.FacesServlet.executeLifecyle(FacesServlet.java:707)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:451)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1628)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:339)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
    at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
    at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:755)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:575)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:520)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:217)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:524)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException
    at com.sun.faces.application.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:76)
    at com.sun.faces.application.ActionListenerImpl.getNavigationOutcome(ActionListenerImpl.java:82)
    ... 82 more
Caused by: java.lang.NullPointerException
    at com.myapp.jsf.user.CounterMB.incrementCounter(CounterMB.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.el.ELUtil.invokeMethod(ELUtil.java:263)
    at javax.el.BeanELResolver.invoke(BeanELResolver.java:494)
    at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:215)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:285)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:65)
    at com.sun.faces.application.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:66)
    ... 83 more

2019-10-24T13:44:12.551+0000|Info: INFO [http-thread-pool::http-listener-1(2)] (LifecycleListener.java:26) - END PHASE INVOKE_APPLICATION 5

一种解决方法是在f:viewParam上渲染=#{not facesContext.postback}",但我认为这不是正确的行为.

A workaround would be to have rendered="#{not facesContext.postback}" on f:viewParam, but I don't think this is the correct behavior.

更新:
在Kukeltje sugestion中,我尝试了使用@ViewScoped的普通JSF应用程序,它可以按预期运行.在isght中,我将继续添加primefaces和spring等.现在的情况.

Update:
At Kukeltje sugestion I have tried with a plain JSF app, with @ViewScoped and it works as expected.With this in isght I'll continue adding primefaces and spring and .... everything that I have in the current app to try simulate the current situation.

更新:

它与普通jsf一起工作的原因是h:commandLink没有发出ajax请求.我能够用以下文件重现它:

The reason it worked with plain jsf was that h:commandLink was not issuing an ajax request. I was able to reproduce it with these files:

`

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />         
        </f:facet>      
        <title> Simulator - Counter rest</title>
    </h:head>

    <h:body>    
        <f:metadata>
            <f:viewParam name="id" value="#{counterMB.id}"/>        
        </f:metadata>

        <h:form id="myForm">
            Id is <h:outputText value="#{counterMB.id}" id="outputTxt"/>

            <h:commandButton value="Increment"update="outputTxt">           
                <f:ajax listener="#{counterMB.incrementCounter()}" execute="myForm" render="outputTxt"/> 
            </h:commandButton>
        </h:form>         
    </h:body>
</html>

`
和这个豆子

`
and with this bean

import java.io.Serializable;

import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class CounterMB implements Serializable{

    private static final long serialVersionUID = 1L;

    private Integer id; 

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        System.out.println("Setting the id with:"+id);
        this.id = id;
    }

    public void incrementCounter() {
        id = id +1;
        System.out.println("Id is="+Integer.toString(id));      
    }
}

推荐答案

我进行了一点搜索,发现了3件事(不确定这根本不是答案,甚至输入答案也不过分)

I have been searching a little and found 3 things (not sure this is the or even an answer at all, but it is too much to type in comments)

  1. 是重复的" 使用javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL导致viewParam为空(未回答,但有一些讨论)
  2. >
  3. 是一个似乎相关的链接 includeViewParams = true将空模型值转换为查询字符串中的空字符串
  4. http://showcase.omnifaces.org/components/viewParam 关于JSF 2.3中与viewParam和null有关的更改.

  1. is a 'duplicate' using javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL causes viewParam to be null (unanswered but some discussion)
  2. is a link that seems to be related includeViewParams=true converts null model value to empty string in query string
  3. is some info from http://showcase.omnifaces.org/components/viewParam about a change in JSF 2.3 related to viewParam and null.

在JSF 2.3中,此问题已修复,并且仅在javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL上下文参数设置为true时才有效.

In JSF 2.3, this has been fixed and has only effect when javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL context param is set to true.

这种组合使我认为您很幸运"它在2.2中有效(确保ID在回发中不为"0"?)老实说,2.3行为感觉"正确.

This combination leads me to think that you 'were lucky' it worked in 2.2 (sure id was not '0' on postbacks?) And honestly, the 2.3 behaviour 'feels' correct.

作为解决方案,您还可以在设置器中添加"null"检查

As a solution you could also add a 'null' check in the setter

void setId(Integer id) {
    if (id != null) {
        this.id = id;
    }
}

或者您可以尝试使用o:viewParam,看看它是否有所不同.

Or you could try the o:viewParam and see if it makes a difference.

这篇关于JSF ViewScope bean,viewParam,ajax请求使用NULL更新MB属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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