Not able to understand the why register method is not being called after prepare. always customeraction-validation.xml is being called

前提是你 提交于 2019-12-14 03:15:20

问题


I am developing a sample web application in struts2. But i am getting some weird behaviour

CustomerAction.java:

package com.astro.action;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.*;
import javax.servlet.*;
import com.astro.model.*;

import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.interceptor.validation.SkipValidation;

//import org.hibernate.classic.Validatable;

import com.astro.base.framework.AstroSystemException;
import com.astro.bo.CustomerBo;
import com.astro.model.Customer;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.Validateable;

public class CustomerAction extends ActionSupport implements  Serializable,SessionAware,Preparable, ModelDriven<CustomerPageInfo>{
    private static final long serialVersionUID = 2335707118972931221L;

    private Map<String,Object> session;
    String target = "";
    //DI via Spring

    private CustomerPageInfo model;
    private CustomerBo customerBo;
    private Customer customer=new Customer();
    public CustomerBo getCustomerBo() {
        return customerBo;
    }
    public void setCustomerBo(CustomerBo customerBo) {
        this.customerBo = customerBo;
    }

    public String errorDisplay()
    {
        return "input";
    }
    //Register a Customer
            public String register() throws Exception{
                System.out.println("I am in register method of CustomerAction.java");
                System.out.println("((())))"+model.getCountryList().toString());
                System.out.println("((())))"+model.getCustomerInfo());
                model.getCustomerInfo().setCreatedDate(new Date());
                 customerBo.register(customer);
                return SUCCESS;
                }

    public void prepare() throws Exception {
        if(model==null)
        {
            model=new CustomerPageInfo();
            System.out.println("In prepare method");
            if(model.getCountryList()==null)
            {
                List<NameValuePair> countryList=customerBo.getAllCountries();
                model.setCountryList(countryList);
            }
            System.out.println("Before initializing"+model.getCustomerInfo());
            if(model.getCustomerInfo()==null)
            {
                model.setCustomerInfo(customer);
            }
            System.out.println("After initializing"+model.getCustomerInfo());
        }

    }

    @Override
    public void setSession(Map<String, Object> map) {
        this.session=map;
    }

    /*public void validate()
    {
        try {
            if(customerBo.doesCustomerExists(customer)==true)
            {
                addActionError("Customer Alreay Exists");
            }
            else
            {
                addActionMessage(INPUT);
            }
        } catch (AstroSystemException e) {
            e.printStackTrace();
        }

    }
*/
    public void setModel(CustomerPageInfo model)
    {

    this.model=model;
    }

    public CustomerPageInfo getModel()
    {
        return model;
    }
}

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.devMode" value="true" />
    <constant name="struts.configuration.xml.reload" value="true" />
    <constant name="struts.action.extension" value="do" />
    <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.custom.i18n.resources" value="ApplicationResources" />
    <!-- <constant name="struts.freemarker.mru.max.strong.size" value="250" /> -->
    <constant name="struts.freemarker.templatesCache.updateDelay"
        value="60000" />
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <package name="astro" extends="struts-default" namespace="/">

        <!-- Different types of result types -->
        <result-types>
            <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
        </result-types>

        <interceptors>
                <interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*,^struts\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>

        </interceptors>
         <action name="registerCustomer" class="customerAction" method="register"> 
            <interceptor-ref name="defaultStack"/>
            <result name="success" type="redirectAction">
                <param name="actionName">successInformation</param>
            </result>
            <result name="input" type="tiles">/registration.tiles</result>
        </action>

        <action name="successInformation" class="com.astro.action.DisplayAction"
            method="display">
            <interceptor-ref name="defaultStack"/>
            <result name="success" type="tiles">/regSuccess.tiles</result>
        </action>

        <action name="loginCustomer" class="loginAction" method="login">
            <result name="success" type="tiles">/loginSuccess.tiles</result>
            <result name="input" type="tiles">/loginForm.tiles</result>
        </action>

        <action name="loginCustomer1" class="loginAction" method="logout">
            <result name="success" type="tiles">/loginForm.tiles</result>
            <result name="input" type="tiles">/loginForm.tiles</result>
        </action>

        <action name="login" class="com.astro.action.DisplayAction1"
            method="display">
            <result name="success" type="tiles">/loginForm.tiles</result>
        </action>
        <action name="feedback" class="com.astro.action.DisplayAction1"
            method="display1">
            <result name="success" type="tiles">/contact.tiles</result>
            <result name="input" type="tiles">/contact.tiles</result>
        </action>
        <action name="contactus" class="contactAction" method="contact">
            <result name="success" type="tiles">/contactus.tiles</result>
            <result name="input" type="tiles">/contactsuccess.tiles
            </result>
        </action>
    </package>

</struts>

customer.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@page session="false"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<style type="text/css">
@import url(css/main.css);
</style>
<style>
.errorMessage {
    color: red;
}
.errors {
    background-color:#FFCCCC;
    border:1px solid #CC0000;
    width:400px;
    margin-bottom:8px;
    font: message-box;
}
.errors li{ 
    list-style: none; 
    }
</style>
<style type="text/css">
.errorsBg{
    background-color:;
    color:black;    
    border: 0px solid;
}

.errorMessage{
    padding:4px 8px;
}

 table{
    border-spacing: 8px;
} 
td{
    padding:5px;
}
</style>
<script>
/* $(document).ready(function(){
  $("input").keydown(function(){
    $("input").css("background-color","yellow");
  });
  $("input").keyup(function(){
    $("input").css("background-color","pink");
  });
}); */
</script>
</head>

<html>
<head>
</head>
<body bgcolor="green">
    <!-- <h1>Welcome to Astro vedic</h1>
    <h2>Register a Customer</h2> -->
    <div class="errors" style="width: 500px">
    <s:token></s:token>
    </div>
<s:if test="hasActionErrors()">
   <div class="errors">
      <s:actionerror/>
   </div>
</s:if>
<s:form action="registerCustomer.do" focusElement="focus" method="post" validate="true" namespace="/">
<s:actionerror /> 
            <s:textfield id="focus" name="name" key="name" size="20" />
            <s:password name="password" label="Password "/>
            <s:password name="confirmPassword" label="Re-enter Password "/>
            <s:textfield name="email" key="email" size="20" required="true" />
             <s:textfield name="telephone" key="telephone" size="20"></s:textfield> 
            <s:select required="true" name="countryCode" label="CountryName" listValue="name" headerKey="" headerValue="Choose One"
            list="countryList" listKey="value"/>  
            <s:submit align="center" key="addCustomer"/>

        </s:form>
    </div>
</body>
</html>

When i am running the code its going to prepare method but not to register method. Not only that if i remove customerAction-validation.xml then its going to register method but nothing is saved in db.

Prepare method is called twice. I am not understanding how to call the register method and customer details get saved.


回答1:


In prepare() you check for model;

model will be set by Params Interceptor (ModelDriven Interceptor should be involved too, not sure how because I've never used ModelDriven), that runs later than Prepare Interceptor, as you can see in your defaultStack definition;

You need to use a stack named paramsPrepareParamsStack, that includes two times the Params Interceptor, one before and one after the Prepare Interceptor, for letting the prepare() method to work with parameters (model or not) coming from the page.

http://struts.apache.org/release/2.3.x/docs/interceptors.html

An example of the paramsPrepareParams trick. This stack is exactly the same as the defaultStack, except that it includes one extra interceptor before the prepare interceptor: the params interceptor.

This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object until at least the ID parameter has been loaded. By loading the parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor to apply the values on the object.



来源:https://stackoverflow.com/questions/16489288/not-able-to-understand-the-why-register-method-is-not-being-called-after-prepare

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!