javax.el.PropertyNotWritableException:/index.xhtml @29,118 value=""": Set Operation 的非法语法

我想创建一个带有本地化选项的登录屏幕来翻译名称,当我从默认英语更改为阿拉伯语时它会崩溃

I want to create a login screen with localization option to translate the name and when i change from the default English to Arabic it crash

这里是 faces.config.xml

here is the faces.config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
     <application>
           <locale-config>
                <default-locale>en</default-locale>
                <supported-locale>ar</supported-locale>
           </locale-config>
       <resource-bundle>
        <base-name>mypack.enar</base-name>
        <var>msg</var>
       </resource-bundle>
     </application>
</faces-config>

托管豆

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

/**
 *
 * @author body
 */
@ManagedBean(name = "localize")
@RequestScoped
public class LocalizeMBean implements Serializable {

    /**
     * @return the countries
     */
    public static Map<String, Object> getCountries() {
        return countries;
    }

    /**
     * @param aCountries the countries to set
     */
    public static void setCountries(Map<String, Object> aCountries) {
        countries = aCountries;
    }

    private String localeCode;

    /**
     * Creates a new instance of LocalizeMBean
     */
    public void setLocaleCode(String localeCode) {
        this.localeCode = localeCode;
    }

    public Map<String, Object> getCountriesInMap() {
        return getCountries();
    }

    public String getLocaleCode() {
        return localeCode;
    }
    private static Map<String, Object> countries;

    static {
        setCountries(new LinkedHashMap<String, Object>());
        getCountries().put("English", Locale.ENGLISH); //label, value
        getCountries().put("Arabic", Locale.UNICODE_LOCALE_EXTENSION);
    }

    public void countryLocaleCodeChanged(ValueChangeEvent e) {

        String newLocaleValue = e.getNewValue().toString();

        //loop country map to compare the locale code
        for (Map.Entry<String, Object> entry : getCountries().entrySet()) {

            if (entry.getValue().toString().equals(newLocaleValue)) {

                FacesContext.getCurrentInstance()
                        .getViewRoot().setLocale((Locale) entry.getValue());

            }
        }
    }
}

JSF 页面

<h:head>
        <title>My Login Page</title>
        <h:outputStylesheet library="mycss" name="login-box.css"/>
    </h:head>
    <h:body>
        <h:form>
            <div style="padding: 100px 0 0 250px;">


                <div id="login-box">

                    <H2>Login</H2>
                    My Login Screen
                    <br />
                    <h:selectOneMenu value="#{localize.localeCode}" onchange="submit();"
                                     valueChangeListener="#{localize.countryLocaleCodeChanged}">
                        <f:selectItems value="#{localize.countriesInMap}" /> 
                    </h:selectOneMenu>
                    <br />
                    <div id="login-box-name" style="margin-top:20px;">
                        <h:outputLabel value="#{msg.namee}" />
                    </div>
                    <div id="login-box-field" style="margin-top:20px;">
                        <h:inputText  styleClass="form-login" title="Username" value="" size="30" maxlength="2048" />
                    </div>
                    <div id="login-box-name">Password:</div><div id="login-box-field"><h:inputSecret styleClass="form-login" title="Password" value="" size="30" maxlength="2048" /></div>
                    <br />
                    <div class="login-box-options"><h:selectBooleanCheckbox value="1"/>Remember me<h:commandLink style="margin-left:30px;" value="Forget Password"/></div>
                    <br />
                    <br />
                    <h:commandButton styleClass="button"/>
                </div>
            </div>
        </h:form>
    </h:body>
</html>

我在组合框中更改时的异常

The Exception when i change in the combobox

javax.faces.component.UpdateModelException: javax.el.PropertyNotWritableException: /index.xhtml @29,118 value="": Illegal Syntax for Set Operation
    at javax.faces.component.UIInput.updateModel(UIInput.java:853)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
    at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)
Caused by: javax.el.PropertyNotWritableException: /index.xhtml @29,118 value="": Illegal Syntax for Set Operation
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
    at javax.faces.component.UIInput.updateModel(UIInput.java:818)
    ... 38 more

推荐答案

请仔细阅读异常信息.答案就在那里.

Please carefully read the exception message. The answer is straight in there.

javax.el.PropertyNotWritableException:/index.xhtml @29,118 value="": 非法集操作语法

javax.el.PropertyNotWritableException: /index.xhtml @29,118 value="": Illegal Syntax for Set Operation

在第 29 行,/index.xhtml 的第 118 个字符,你有一个 value="".对于应该可以通过 setter 方法写入的 EL 值表达式,这不是有效的语法.

At line 29, character 118 of /index.xhtml you've a value="". This is not a valid syntax for an EL value expression which should be writable through a setter method.

通常,您像 value="#{bean.property}" 这样指定 value 属性,其中 bean 有一个 getProperty() 和一个 setProperty() 方法符合 javabeans 规范.

Normally, you specify the value attribute like so value="#{bean.property}" wherein the bean has a getProperty() and a setProperty() method conform javabeans specification.

很可能是这个:

<h:inputText  styleClass="form-login" title="Username" value="" size="30" maxlength="2048" />

我不确定您为什么要这样指定值.这是完全错误的.您应该完全删除它

I'm not sure why you specified the value like that. This is plain wrong. You should either remove it altogether

<h:inputText  styleClass="form-login" title="Username" size="30" maxlength="2048" />

或将其绑定到有效的 bean 属性

or bind it to a valid bean property

<h:inputText  styleClass="form-login" title="Username" value="#{someBean.userName}" size="30" maxlength="2048" />

请注意,此问题与更改 JSF 语言环境无关.

Please note that this problem has nothing to do with changing the JSF locale.

与具体问题无关,嵌套表单在 HTML 中是非法,因此也在JSF中.您应该将语言选择和用户登录拆分为 2 个单独的表单.您不想在更改语言时提交登录数据.此外,您可能会发现此答案中的提示有助于正确更改 JSF 语言环境:JSF 中的本地化,如何记住每个会话而不是每个请求/视图选择的语言环境

Unrelated to the concrete problem, nesting forms is illegal in HTML and therefore also in JSF. You should split the language selection and the user login over 2 separate forms. You don't want to submit the login data when you change the language. Further, you may find the hints in this answer helpful as to how to properly change the JSF locale: Localization in JSF, how to remember selected locale per session instead of per request/view

相关文章