【问题标题】:ManagedBean method is changing dataTable objectManagedBean 方法正在更改 dataTable 对象
【发布时间】:2018-11-17 16:35:06
【问题描述】:

我有一个<p:dataTable />,它列出了我正在工作的网页的“系统参数”。其中一个参数是邮件服务器密码,它在数据库中以 Base64 编码。在数据表的最后一列中,我有一个按钮来编辑该参数,当我单击它时,会显示一个引导模式,其中包含“名称”和“值”字段。

我有一个 @ViewScoped 范围的 ManagedBean,还有一个函数,它还可以识别要编辑的参数是否是邮件服务器密码,以解码值。该方法将对象作为参数获取数据表迭代对象。我的问题是我第一次打开模态时,对象的值是正确的,但是在第二次对象值发生变化并生成异常时,因为该值已经解码,并且该值里面有一个点并且它生成错误。

我不明白为什么我从不按字面更改数据表对象的值。

我正在使用 PrimeFaces、BootsFaces、JSF 2.2。这是我的<p:dataTable />

<p:dataTable value="#{parameterBean.listParameter}" var="p" 
                         paginator="true" rows="10" 
                         reflow="true" id="tblParameter" 
                         emptyMessage="No data available.">
    <!-- Some columns -->

    <p:column headerText="Options">
        <b:commandButton value="Edit" icon="edit" look="info" 
                         ajax="true" update="parametroForm" 
                         onclick="ajax:parameterBean.editParameter(p)" 
                         oncomplete="$('#parameterModal').modal('show');" />
</p:dataTable>

这是我的 bean 方法:

public void editParameter(TblParameter p) {
   System.out.println("ENCODE: " + p.getVlrParameter());
    this.param = new TblParameter(); //- This is an object in the bean to access it from modal form.

    try {
        setParam(p);

        if (getParam().getIdParameter().equals(new Long(4))) {//- Validate if is the server mail password.
            byte[] clv64 = Base64.getDecoder().decode(p.getVlrParameter().getBytes());
            getParam().setVlrParameter(new String(clv64));
        }

    } catch(Exception e) {
        System.out.println("Error: " + e.getMessage());
        e.printStackTrace();
    }
}

最后,正如我所说,当我第一次打开模态时,打印的输出是这样的:

ENCODE: MTIzLjQ1Ng==

但第二次显示:

ENCODE: 123.456
java.lang.IllegalArgumentException: Illegal base64 character 2e
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
at com.abcpagos.otis.beans.admin.ParametroBean.editarParametro(ParametroBean.java:146)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)...

如果有人能解释一下这种行为,我将不胜感激。

【问题讨论】:

  • 虽然这与您的问题无关:从安全的角度来看,永远不要解码密码。始终使用编码版本。一些黑客有工具扫描内存以获取密码。只要他们只能看到编码版本,就没有什么坏处。另外,您应该采用单向加密。应该没有办法从加密密码表的副本中猜出未加密的密码。
  • 非常感谢您的建议;我决定对密码进行解码,以防用户想要保留相同的密码但添加一些字符,例如,如果密码是123.456,而用户现在想要123.45677。但我认为最好让用户在想要更改密码时始终填写完整的密码。

标签: primefaces jsf-2.2 bootsfaces


【解决方案1】:

实际上,您确实会意外更改参数。看看这些行:

byte[] clv64 = Base64.getDecoder().decode(p.getVlrParameter().getBytes());
//                                          ^^^^^^^^^^^^^^^
getParam().setVlrParameter(new String(clv64));
//         ^^^^^^^^^^^^^^^                

所以第二次尝试解码已经以纯文本形式存储的参数。

【讨论】:

  • 可能我有点糊涂了,但我还是不明白,因为p对象与getParam()方法关联的对象不一样。在我的 bean 中,我声明了一个 private TblParameter param;,我用它来显示模态形式的数据(来自 dataTable 对象的数据),所以理论上我不会覆盖 dataTable 对象,因为我只使用它是为了获取价值,对吗?
  • 你确定p.getVlrParameter()getParam() 是不同的对象吗?我无法从您向我们展示的那个小源代码中判断这一点。但是,经常发生开发人员复制变量而没有考虑变量只是对内存位置的引用(或指针)的情况。我想这也是这里发生的事情。通常,我通过检查 Eclipse 调试器中的变量来追踪此类错误。在调试器窗口中,它不仅显示值,还显示id。这个id 是(某种)指向内存位置的指针。你的变量是否共享一个共同的id
  • 顺便说一句,我想同样的技巧也适用于其他 IDE。
  • 我明白了,可能是对象引用。我将尝试调试代码。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-07-25
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
相关资源
最近更新 更多