struts2 提交数据到Action 老是报出异常: Inappropriate OGNL expression: null,请高手来,要具体原因。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struts2 提交数据到Action 老是报出异常: Inappropriate OGNL expression: null,请高手来,要具体原因。相关的知识,希望对你有一定的参考价值。

INFO - Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
WARN - Error setting value
ognl.InappropriateExpressionException: Inappropriate OGNL expression: null
at ognl.SimpleNode.setValueBody(SimpleNode.java:257)
at ognl.SimpleNode.evaluateSetValueBody(SimpleNode.java:177)
at ognl.SimpleNode.setValue(SimpleNode.java:246)
at ognl.Ognl.setValue(Ognl.java:476)
at com.opensymphony.xwork2.ognl.OgnlUtil.setValue(OgnlUtil.java:192)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:155)
at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:143)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.setParameters(ParametersInterceptor.java:273)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:187)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:148)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:93)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:306)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:128)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:104)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
这个是补充的整体异常。 解决好的附加。

参考技术A 从页面向后台Action传递参数
a.直接传值
在前台页面写<a href="user/user!add?name=a&age=8">
后台Action中必须有name和age的get,set方法
b.使用域模型传递参数
在前台页面写<a href="user/user!add?user.name=a&user.age=8">
在后台Action中有一个对象user的get和set方法。对象user所在的类有对应的name、age的get,set方法
c.ModelDriven
在前台页面写<a href="user/user!add?name=a&age=8">
后台放的是一个对象,和b不同的是类继承了一个接口implements ModelDriven<User>,其中User是对象user对应的类名
没有user的set和get方法,而是
@Override
public User getModel()return user;
这是我之前学习struts2时做的笔记。你看看能帮你解决问题不。本回答被提问者采纳

关于struts2防止表单重复提交

struts2防表单重复提交有两种方式。

其一是action的重定向,跳转时设置type为从一个action跳转到另一个action或者另一个页面,

使用户提交后,所停留的位置,不是当前处理数据的Action,这样用户再刷新时,就不会再次执行这个Action了,

就会避免表单重复提交的问题了。

其二就是session令牌的方式(token)

处理也很方便,只需要在所提交的表单上加一个struts2标签  <s:token>

注意在该页面需要导入  <%@taglib prefix="s" uri="/struts-tags"%>

这样,当浏览器第一次访问这个带有<s:token>标签的页面时,在服务器中,解析<s:token>标签的类(TokenTag.class),

会生成一个随机的字符串(这个字符串,查看网页的源代码可以看到),并且发送给客户端的浏览器,同时,在服务器中,

会把这个随机字符串保存到用户的session对象中。

当第一次提交表单时,在服务器中,会比较客户端和服务器中分别保存的这个随机字符串,因为是第一次提交,

所以这两个字符串相等,然后进行正常的业务处理。第一次提交后,在服务器中的session中保存的这个随机字符串,

会改变为其他的随机值,注意,这是很重要的一步!此时,地址栏停留在处理用户提交数据的Action中,

客户端中保存的随机字符串没有改变,若是刷新页面,即重复提交,服务器再进行两个字符串的比较,

会不相等,就会跳转到name为invalid.token的结果页面中,这样就会防止表单重复提交了。

贴上示例代码

struts_regist.jsp

 1 <%@ taglib prefix="s" uri="/struts-tags" %>
 2 <%--
 3   Created by IntelliJ IDEA.
 4   User: leslie
 5   Date: 17-12-2
 6   Time: 上午10:46
 7   To change this template use File | Settings | File Templates.
 8 --%>
 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
10 <html>
11 <head>
12     <title>注册</title>
13 </head>
14 <body>
15     <form action="${pageContext.request.contextPath}/struts_regist" method="post">
16         <s:token />
17         用户名:<input type="text" name="name"><br>
18         密&nbsp;&nbsp;&nbsp;&nbsp;码:<input type="password" name="password"><br>
19         <input type="submit" value="注册">
20     </form>
21 </body>
22 </html>

struts.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE struts PUBLIC
 3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
 4     "http://struts.apache.org/dtds/struts-2.3.dtd">
 5 
 6 <struts>
 7     <package name="default" namespace="/" extends="struts-default">
 8         <action name="regist" class="cn.itcast.action.RegistAction">
 9             <result name="invalid.token">/token.jsp</result>
10             <interceptor-ref name="token" />
11             <interceptor-ref name="defaultStack" />
12         </action>
13     </package>
14 </struts>

token.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@taglib prefix="s" uri="/struts-tags"%>
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>My JSP ‘index.jsp‘ starting page</title>
 7   </head>
 8 
 9   <body>
10     <s:actionerror/>
11   </body>
12 </html>

 

RegistAction

 1 package com.emuii.action;
 2 
 3 import com.opensymphony.xwork2.ActionSupport;
 4 import org.apache.struts2.ServletActionContext;
 5 
 6 public class RegistAction extends ActionSupport {
 7 
 8     @Override
 9     public String execute() throws Exception {
10 
11        String name = ServletActionContext.getRequest().getParameter("name");
12        String password = ServletActionContext.getRequest().getParameter("password");
13 
14        System.out.println(name+":"+password+"已注册");
15 
16        return null;
17     }
18 }

如果想要自定义错误信息,只需在action同一目录下创建一个 ----类名.properties配置文件即可

RegistAction.properties

1 struts.messages.invalid.token=\u60A8\u5DF2\u7ECF\u91CD\u590D\u63D0\u4EA4\u8868\u5355\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5

另:对于只有一个action来说,通配符跳转的方式第一种防表单提交无效的,虽然重定向之后的jsp页面不一样。

如果需要对特定的方法进行防表单提交这样:

1 <action name="someAction" class="com.examples.SomeAction">
2      <interceptor-ref name="token">
3         <param name="includeMethods">myMethod</param>
4      </interceptor-ref name="token"/>
5      <interceptor-ref name="basicStack"/>
6      <result name="success">good_result.ftl</result>
7  </action>

<param name="includeMethod">xx</param>表示只拦截xx方法

<param name="excludeMethod">xx</param>表示拦截xx方法之外的方法

另:WARN [org.apache.struts2.util.TokenHelper] - Could not find token name in params.出现这个问题,

也有可能是你没对指定方法进行拦截,当然情况不一定非是这种的,只是因为我的项目问题才导致这个问题的。



以上是关于struts2 提交数据到Action 老是报出异常: Inappropriate OGNL expression: null,请高手来,要具体原因。的主要内容,如果未能解决你的问题,请参考以下文章

Struts2---将页面表单中的数据提交给Action

struts2 action在前台显示信息提示

struts2入门之action获取表单提交数据

关于struts2防止表单重复提交

理解Struts2的Action中的setter方法是怎么工作的

Struts2 06--系统拦截器防止数据重复提交