6

我正在尝试通过 JavaScript 将字段的值发送到 Struts2 后端,但它返回NullpointerException.

<input type="hidden" id="employee.payslip.id" name="employee.payslip.id" value="5"/>
....

提交表单后,请求将被发送到以下 JavaScript 方法以发送到后端。

 function payslipPayment(){

     var formValues = $('#myform').serialize();
     ....
     xmlhttp.open("get","../payslip/pay?"+formValues,false);
     xmlhttp.send();

 }

请求将按如下方式创建和发送

http://localhost/payslip/pay/employee.payslip.id=5&employee.payslip.year=2013&....

但是在后端,当我尝试显示它返回的值时NullPointerException

爪哇:

public class payslip {

 private Employee employee;

 public String pay{
    System.out.println("Id:"+employee.payslip.id):
    System.out.println("Year:"+employee.payslip.year;
    ...
 }

 getter and setter 

}

课程:

public class Employee {
   private Payslip payslip;
   ....
   getter and setter
}

public class Payslip{
  private long id;
  ...
  getter and setter
}
4

8 回答 8

3

空指针异常意味着未初始化员工或工资单。如果您使用的是 struts2,那么使用参数拦截器和模型驱动方法应该可以解决您的问题。

于 2013-11-08T17:57:01.753 回答
2
  • 您需要将表单转换为 json(如这里)并发送到后端
  • 然后 - 在 java 中,您需要将 json 反序列化为 java 对象(例如,使用Jackson
于 2013-11-07T04:24:01.430 回答
2

Struts2 使用params拦截器来填充由 HTTP 请求提交的表单值。

建议使用POST方法,因此如果您有敏感数据并且您希望它不会反映在 URL 中。

拦截器使用参数名称通过 OGNL 运行时来评估应该.valueStack

你已经得到了NullPointerException,因为你没有初始化或注入对 OGNL 评估引用的对象的依赖项。因为您使用的是嵌套 bean,所以所有嵌套属性都应该是可访问和初始化的(或者至少 Struts2 知道如何创建这些对象),并且属于放置在top值堆栈上的操作类。

于 2013-11-09T19:41:46.663 回答
2

在动作标签中添加输入参数;这使您可以将参数从 struts 动作类传递到 form/.jsp

struts.xml

<action name="..." class="UserAction">
 <param name="id"></param>
 <result name="input">/WEB-INF/jsp/User.jsp</result>
</action>

动作类

public class UserAction {
private int id;

// this is called by the struts.xml to set the value
public void setId(int id) {
this.id = id;
}

//a getter is needed as well to display value in the .jsp

}

因为,它是一个隐藏变量,不是 valuestack 的一部分,您可以尝试以这种方式传递它。

如果这不是您的问题;我认为你必须将 bean 注入到 Action 类中。@注入员工;将 bean 放入 Action 类会有所帮助。

还要调试值堆栈。

于 2013-11-12T21:24:50.930 回答
2
  1. 为 Employee & Payslip 实现可序列化的接口。另外,确保两者都有空的构造函数。

  2. 为其他日志启用 struts2 devMode。启用后,您将看到 OGNL 异常,特别是关于哪个字段给出了问题。该错误必须非常直接地处理。http://www.mkyong.com/struts2/struts-2-development-mode-example/

  3. 我想用于该操作的拦截器堆栈存在一些问题,只需尝试使用 defaultStack。

<action name="payslip/pay" class="...">
    <interceptor-ref name="defaultStack"/>
    <result name="success">/success.jsp</result>
    <result name="input">/error.jsp</result>
</action>
于 2013-11-10T06:54:06.170 回答
2

您可以像 Alexey 所说的那样做,也可以遵循这种方法。您可以使用接口 ServletRequestAware 和 ServletResponseAware 然后使用 request.getParameter() 来获取传递的值。以下是如何执行此操作的示例。

动作类struts配置

<action name="hello" method="execute"
            class="com.home.struts2.HelloAction">
            <result name="success">hello.jsp</result> 
        </action>

动作类

 public class HelloAction extends ActionSupport implements ServletRequestAware,ServletResponseAware{
        HttpServletResponse response;
        HttpServletRequest request;

        public String execute() {

             System.out.println("AjaxCall" + request.getParameter("param"));
              String infoXml = "Parameter passed: " + request.getParameter("param");
              response.setContentType("text/html");
                response.setHeader("Cache-Control", "no-cache");
                try {
                    response.getWriter().write(infoXml);
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }

                return null;

        }

        public void setServletResponse(HttpServletResponse response) {
            this.response = response;
        }

        public void setServletRequest(HttpServletRequest request) {
            this.request = request;
        }

        public HttpServletRequest getServletRequest() {
            return this.request;
        }

    }

JavaScript

var xmlHttp;
function sendreq(){  

        var URL = "hello.action?param=sandy";
        try{
            xmlHttp=new XMLHttpRequest();
        }catch (e){
            try{
                xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
            }catch (e){
                try{
                    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                }catch (e){
                    alert("Your browser does not support AJAX!");
                    return false;
                }
            }
        }

        xmlHttp.onreadystatechange = showMessage;

        xmlHttp.open("GET", URL, true);

        xmlHttp.send(null);
    }
于 2013-11-07T05:50:49.567 回答
2

您使用的是框架,还是只是一个普通的 servlet?如果您使用的是 struts 之类的框架,那么所有这些答案都太复杂了。

我认为从外观上看,您只使用了一个映射的 servlet,这意味着上面的答案对于通过 url 传递命名参数是正确的。您可以使用 post 隐藏这些命名参数,而不是 get 。

下面是我将如何只使用一个 servlet 来做到这一点。不过,如果我是你并且做一个完整的项目,我会使用 JSF,以便更轻松地传递数据。

爪哇

public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    String payslipID = request.getParameter("payslipid");
}

js

<script>
var payslipid = $('#employee_payslip_id')
xmlhttp.open("POST","../payslip/pay",false);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("payslipid="+payslipid);
</script>

正如在另一篇文章中提到的那样,除非您做了一些单独的字符串列表,否则您必须单独获取(并放置在帖子中或获取获取数据)所有参数。这样做并不是一件很荒谬的事情,因为无论如何您都需要将所有这些值分离到它们自己的 java 变量中。

编辑:

上面的答案实际上说明了您需要做什么,但也许有助于使其更清楚。在您定义操作的 struts 配置文件中,例如

<action class="org.example.Payslip" name="payslip">
            <interceptor-ref name="params"/>
            <result name="success">/success.jsp</result>
</action>

确保那里有 params 拦截器。它将使服务器将参数映射到设置器。然后你就不需要为你发送的每一件事都调用 getparameter 了。

此外,如果您按照上面的方式进行了映射,则 url 应该类似于 .../payslip.action!pay?payslipid=1234&employeeid=1234。这告诉它使用 payslip.class 和 pay 函数。

于 2013-11-07T16:16:02.203 回答
1

您需要使用 ModelDriven 接口。实现 ModelDriven 并覆盖其方法,然后使用 modelDriven 的方法返回您的对象。

Struts2 文档

于 2013-11-14T07:52:00.277 回答