FreeMarker 模板错误!在struts2中

2023-12-29

我在类中使用基于 Sturts 2 注释的验证,同时显示操作错误,我收到了这个奇怪的“FreeMarker 模板错误!”这是我的实体类。

@Entity
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long userid;
    private String userPhoneNumber;
    private String userName;
    private String password;
    private String full_name;
    private String useremail;

    @OneToOne
    private userType usertypeid;

    public Long getUserid() {
        return userid;
    }

    public void setUserid(Long userid) {
        this.userid = userid;
    }

    public String getUserPhoneNumber() {
        return userPhoneNumber;
    }

    @RequiredStringValidator(message = "Enter Phone Number",type = ValidatorType.FIELD)
    public void setUserPhoneNumber(String userPhoneNumber) {
        this.userPhoneNumber = userPhoneNumber;
    }

    public String getUserName() {
        return userName;
    }

    @RequiredStringValidator(message = "Enter User Name",type = ValidatorType.FIELD)
    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    @RequiredStringValidator(message = "Enter Password",type = ValidatorType.FIELD)
    public void setPassword(String password) {
        this.password = password;
    }

    public String getFull_name() {
        return full_name;
    }

    @RequiredStringValidator(message = "Enter Full Name",type = ValidatorType.FIELD)
    public void setFull_name(String full_name) {
        this.full_name = full_name;
    }

    public String getUseremail() {
        return useremail;
    }

    @RequiredStringValidator(message = "Enter Email Id",type = ValidatorType.FIELD)
    @EmailValidator(message = "Enter Valid Email Id",type = ValidatorType.FIELD)
    public void setUseremail(String useremail) {
        this.useremail = useremail;
    }

    public userType getUsertypeid() {
        return usertypeid;
    }

    public void setUsertypeid(userType usertypeid) {
        this.usertypeid = usertypeid;
    }

}

这是我的 Struts.xml 文件操作代码

<action name="saveorupdate" class="com.elegant.purchasemodule.purchasemasters.user.UserAction"
            method="saveOrUpdate">
    <interceptor-ref name="defaultStackHibernateStrutsValidation"/>
    <result name="input">/AddUser.jsp</result>
    <result name="success" type="redirect">userlist</result>
</action>

这是我的jsp页面

<s:form  action="saveorupdate" method="post" cssClass="form-horizontal"  theme="simple" >
    <s:push value="u">
        <s:hidden name="userid" id="userid"></s:hidden>
            <fieldset>
                <legend>User</legend>
                <div class="form-group">
                    <label class="col-md-3 control-label" for="textinput">User Name</label>  
                    <div class="col-md-3">
                    <s:textfield id="userName" name="userName" cssClass="form-control input-md"></s:textfield>
                        <div id="userNameError" style="color: red"></div>
                    <s:fielderror fieldName="userName" cssClass="alert-danger"/>
                </div>
            </div> 

            <div class="form-group">
                <label class="col-md-3 control-label" for="textinput">Full Name</label>  
                <div class="col-md-3">
                    <s:textfield id="full_name" name="full_name" cssClass="form-control input-md" ></s:textfield>
                    <div id="full_nameError" style="color: red"></div>
                    <s:fielderror fieldName="full_name" cssClass="alert-danger"/>
                </div>
            </div> 
            <div class="form-group">
                <label class="col-md-3 control-label" for="textinput">Contact No</label>  
                <div class="col-md-3">
                    <s:textfield id="userPhoneNumber" name="userPhoneNumber" cssClass="form-control input-md"></s:textfield>
                    <div id="contactNoError" style="color: red"></div>
                    <s:fielderror fieldName="userPhoneNumber" cssClass="alert-danger"/>
                </div>
            </div> 
            <div class="form-group">
                <label class="col-md-3 control-label" for="textinput">Email Id</label>  
                <div class="col-md-3">
                    <s:textfield id="useremail" name="useremail" cssClass="form-control input-md" ></s:textfield>
                    <div id="emailIdError" style="color: red"></div>
                    <s:fielderror fieldName="useremail" cssClass="alert-danger"/>
                </div>
            </div> 
            <div class="form-group">
                <label class="col-md-3 control-label" for="textinput">Password</label>  
                <div class="col-md-3">
                    <s:password id="password" name="password" cssClass="form-control"/>
                    <div id="passwordError" style="color: red"></div>
                    <s:fielderror fieldName="password" cssClass="alert-danger"/>
                </div>
            </div>    
            <div class="form-group">
                <label class="col-md-3 control-label" for="selectbasic">User Type</label>
                <div class="col-md-3">
                    <s:select id="UserType"
                              label="UserType" 
                              headerKey="-1" headerValue="Select Status"
                              list="usertylist"
                              listValue="usertypename"
                              listKey="usertypeid"
                              cssClass='form-control input-md'
                              name="usertypeid.usertypeid"/>
                </div>
                <div id="UserTypeError" style="color: red"></div>
            </div>  
            <div class="form-group">
                <label class="col-md-4 control-label" for="singlebutton">&nbsp;</label>
                <div class="col-md-4">
                    <button id="save" type="submit"  name="save" class="btn btn-primary">Save</button>&nbsp;
                    <button type="reset" value="reset" class="btn btn-primary">Reset</button>
                    <button type="button" onclick="window.location.href = 'userlist'" class="btn btn-primary ">Cancel</button>&nbsp;

                </div>
            </div>
        </fieldset>
    </s:push>
</s:form>

提交表单后,即使我提供了有效的详细信息,它仍显示此错误

 org.apache.jasper.JasperException: Expression eKey is undefined on line 32, column 23 in template/simple/fielderror.ftl. - Class: freemarker.core.TemplateObject
File: TemplateObject.java
Method: assertNonNull
Line: 125 - freemarker/core/TemplateObject.java:125:-1
at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:570)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:457)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:164)
at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept    (AnnotationValidationInterceptor.java:68)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:249)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:249)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept   (ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.intercept   (SessionTransactionInjectorInterceptor.java:157)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter   (StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

例外是告诉您在哪里查找错误:

org.apache.jasper.JasperException:模板/简单/中第 32 行第 23 列上的表达式 eKey 未定义字段错误.ftl。 - 类:freemarker.core.TemplateObject

罪魁祸首是一个fieldError与一个不匹配的fieldName.经过测试(在评论中)后结果是full_name, 显然下划线未正确处理贯穿整个链条:

<s:textfield id="full_name" name="full_name" ... />
...
<s:fielderror fieldName="full_name" cssClass="alert-danger"/>

full_name那么应该改为fullName只要使用变量及其 Getter 和 Setter 即可工作:

<s:fielderror fieldName="fullName" cssClass="alert-danger"/>

还要确保拥有所有最新且一致的 struts 库和插件,以及正确版本的外部依赖项(Hibernate 验证器等)


也就是说,我想给你一些关于变量命名的建议:

  1. 对于具有多个单词的变量,始终使用驼峰命名法:password is password(一个词,虽然是复合词),但是username and useremail应该userName and userEmail。您对单个类的 6 个变量使用了 3 种不同的约定...

  2. 由于这些是变量User类,避免冗余user在变量名称中:userid = id、用户名 = 名称、userPhoneNumber = 电话号码等... 如果您这样做是为了提高 JSP 的可读性,那么就避免使用<s:push>可能会造成混淆的标签。

如果您刚开始,更改数据库列名称应该不会很痛苦...否则,请为您的下一个项目保留此建议。

P.S:请注意,使用 JPA 和 Hibernate,您可以使用驼峰命名法变量和带下划线的列名称(phoneNumber在实体中,phone_number在数据库中)自动使用 persistence.xml 中的此设置:

<property name="hibernate.ejb.naming_strategy"
         value="org.hibernate.cfg.ImprovedNamingStrategy" />
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeMarker 模板错误!在struts2中 的相关文章

随机推荐

  • form_for 的路由范围问题(部分)

    尝试路由 scope shortcut do resources text elems end 使用带有表单部分的基本脚手架 form html erb 问题是 当我打电话时edit动作 表单 html 显示为
  • UserDefaults 不使用 Swift 保存

    我正在尝试使用 UserDefaults 来持久保存布尔值 这是我的代码 public static var isOffline UserDefaults standard bool forKey isOffline didSet prin
  • 在 JExcelApi 中制作新颜色

    我正在使用 JExcelApi 生成 XLS 文件 从jxl format 颜色 http jexcelapi sourceforge net resources javadocs 2 6 10 docs jxl format Colour
  • 拥有许多小型 Azure 存储 Blob 容器(每个容器都包含一些 Blob)更好,还是拥有一个包含大量 Blob 的大型容器更好?

    所以场景如下 我有一个 Web 服务的多个实例 用于将 blob 数据写入 Azure 存储 我需要能够根据收到的时间将 blob 分组到容器 或虚拟目录 中 偶尔 最坏的情况是每天 旧的 blob 会被处理然后删除 我有两个选择 Opti
  • 带延迟的打字稿循环

    我正在尝试用 Typescript 创建一个节拍器 我有这个 JavaScript 代码 function theLoop i setTimeout function metronome play if i theLoop i 3000 i
  • 是否可以使用 MSTest 从 c++ dll 测试“内部”类?

    我们目前正在尝试向我们的 C 应用程序添加单元测试 该应用程序由 30 个项目组成 生成 29 个 dll 和 1 个 exe 我们使用 MSTest 来运行我们的单元测试 因为它已经包含在 Visual Studio 2010 中 它对于
  • 巩固党规

    一个简单的例子 gt library partykit gt partykit list rules party ctree Petal Length data iris 2 Petal Width lt 0 6
  • 关于创建表作为选择 (CTAS)

    当我们这样做时 create table big2 as select from big1 索引和约束是否也复制到新表中 仅复制 NOT NULL 约束 看FAQ http www orafaq com wiki CTAS 你可以做CREA
  • SQL 中的离散导数

    我的表格中有传感器数据 格式如下 Time Value 10 100 20 200 36 330 46 440 我想提取每个时间段的值变化 理想情况下 我想得到 Starttime Endtime Change 10 20 100 20 3
  • Django 自定义用户字段与 AbstractBaseUser 冲突

    我正在从现有数据库构建 Django 项目 该数据库正在被其他系统使用 因此我无法更改其架构 这是我当前的自定义用户模型 class Users AbstractBaseUser id user models IntegerField pr
  • 添加到 iPhone 主屏幕时,Web 应用程序感觉响应速度较慢

    当添加到 iPhone 上的主屏幕时 这个 Angular 2 应用程序的响应速度比在 Safari 中运行时的响应速度要慢 我通过将其添加到 index html 使其具有 Web 应用程序功能 如果你有几分钟时间 在 Github 页面
  • 在 Xcode 中,视图或窗口如何知道自身外部的 mouseDown?

    我想设计一个有点像弹出窗口的面板 当鼠标在它外面按下时 它可能会关闭或隐藏自己 但我不知道如何实现这一目标 我所知道的是一个视图可以处理 mouseDown mouseUp等等 但是当鼠标在其他地方按下时呢 我不知道如何捕捉这个事件 进一步
  • 如何使用 16GB 内存创建 Windows 虚拟机

    我对云服务完全陌生 使用 Windows Azure 我需要一个 Web 服务器和一个数据库服务器 每个服务器都有 16GB RAM 然而 超大的 Windows 虚拟机只有 14GB RAM 我如何为每台服务器添加 2GB RAM 或者我
  • rabbitmq 抛出 AmqpException: 找不到类 [B

    当我向 RabbitMQ 发送消息时 它会抛出 AmqpException for 循环 org springframework amqp rabbit listener exception ListenerExecutionFailedE
  • 通过 Git 将 Master 上未提交的更改放入新分支

    当我在分支时 如何将未提交的更改放入分支测试master 您还可以创建一个新分支并通过执行以下操作切换到它 git checkout b new branch git add 我一直使用这个 因为我总是忘记在开始编辑代码之前启动一个新分支
  • Alphavantage 和纳斯达克指数停止运行

    这个针对纳斯达克综合指数的 API 调用曾经有效 现在它只返回一个空的 JSON 没有错误消息 https www alphavantage co query function TIME SERIES MONTHLY symbol IXIC
  • webkit translateX 动画正在回滚到初始位置

    我正在尝试为移动 webkit 制作一个图片库 实际上足够快的唯一方法是使用硬件加速的translateX 我的问题是 div 在动画结束时收回其初始位置 我在左侧按钮上添加了 SlideGalLeft 类 到动画 div 您可以在此处的回
  • D3.js 使用嵌套数组从 tsv 迁移到 json

    我正在通过遵循教程并尝试阅读可用的示例来学习 d3 js 感谢迈克 在这个例子中 http bl ocks org mbostock 3884955 http bl ocks org mbostock 3884955 我无法理解如何从 ts
  • RxJava2 发布

    有什么区别 ObservableTransformer Observable merge it ofType x compose transformerherex it ofType y compose transformerherey a
  • FreeMarker 模板错误!在struts2中

    我在类中使用基于 Sturts 2 注释的验证 同时显示操作错误 我收到了这个奇怪的 FreeMarker 模板错误 这是我的实体类 Entity public class User implements Serializable priv