具有嵌套对象的Spring表单会引发目标对象绑定错误

时间:2013-06-19 11:29:44

标签: java forms spring spring-mvc

我正在尝试将Spring表单与我的控制器一起使用,并且它映射到的实体具有嵌套对象。当尝试使用表单命中页面时,它会抛出以下错误。

我没有正确初始化模型吗?

控制器:

@RequestMapping(value = "/payPal2",
        headers = "Accept=application/json",
        method = RequestMethod.POST)
public
@ResponseBody
Payment payByCreditCard2(@ModelAttribute("orderContext") OrderContext orderContext, Model model) throws Exception {
    PaymentWithCreditCard paymentWithCreditCard = new PaymentWithCreditCardImpl();
    model.addAttribute("billingAddress", new Address());

    OTHER Setters and getters down here

表格:

<form:form modelAttribute="orderContext" method="post" action="/service/payments/payPal2">
    <form:input path="billingAddress.city"/>
</form:form>

错误:

org.apache.jasper.JasperException: An exception occurred processing JSP page /paypalTest.jsp at line 14

11: </head>
12: <body>
13: <form:form modelAttribute="orderContext" method="post" action="/service/payments/payPal2">
14:     <form:input path="billingAddress.city"/>
15: </form:form>
16: </body>
17: </html>

root cause

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'orderContext' available as request attribute
    org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:178)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:198)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:164)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.autogenerateId(AbstractDataBoundFormElementTag.java:151)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:142)
    org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:126)
    org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:421)
    org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
    org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
    org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
    org.apache.jsp.paypalTest_jsp._jspx_meth_form_005finput_005f0(paypalTest_jsp.java:151)
    org.apache.jsp.paypalTest_jsp._jspx_meth_form_005fform_005f0(paypalTest_jsp.java:116)
    org.apache.jsp.paypalTest_jsp._jspService(paypalTest_jsp.java:77)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)

订单背景:

import com.paypal.api.payments.*;
import com.paypal.api.payments.Address;

import java.util.List;

public class OrderContext {
    private com.paypal.api.payments.Address billingAddress;
    private CreditCard creditCard;
    private Details details;
    private Amount amount;
    private List<Transaction> transactions;
    private List<FundingInstrument> fundingInstruments;
    private Payer payer;
    private Payment payment;

    public Address getBillingAddress() {
        return billingAddress;
    }

    public void setBillingAddress(Address billingAddress) {
        this.billingAddress = billingAddress;
    }

    public CreditCard getCreditCard() {
        return creditCard;
    }

    public void setCreditCard(CreditCard creditCard) {
        this.creditCard = creditCard;
    }

    public Details getDetails() {
        return details;
    }

    public void setDetails(Details details) {
        this.details = details;
    }

    public Amount getAmount() {
        return amount;
    }

    public void setAmount(Amount amount) {
        this.amount = amount;
    }

    public List<Transaction> getTransactions() {
        return transactions;
    }

    public void setTransactions(List<Transaction> transactions) {
        this.transactions = transactions;
    }

    public List<FundingInstrument> getFundingInstruments() {
        return fundingInstruments;
    }

    public void setFundingInstruments(List<FundingInstrument> fundingInstruments) {
        this.fundingInstruments = fundingInstruments;
    }

    public Payer getPayer() {
        return payer;
    }

    public void setPayer(Payer payer) {
        this.payer = payer;
    }

    public Payment getPayment() {
        return payment;
    }

    public void setPayment(Payment payment) {
        this.payment = payment;
    }

    @Override
    public String toString() {
        return "OrderContext{" +
                "billingAddress=" + billingAddress +
                ", creditCard=" + creditCard +
                ", details=" + details +
                ", amount=" + amount +
                ", transactions=" + transactions +
                ", fundingInstruments=" + fundingInstruments +
                ", payer=" + payer +
                ", payment=" + payment +
                '}';
    }
}

2 个答案:

答案 0 :(得分:1)

我相信你必须在你的控制器中创建两个方法:一个处理表单显示(GET),另一个处理表单一旦提交(POST)。

您只使用POST方法,即在提交后收到表单数据。

// just displays the form
@RequestMapping(value = "/payPal2", method = RequestMethod.GET)
public String payByCreditCardGet(@ModelAttribute("orderContext") OrderContext orderContext, Model model) throws Exception {
    // orderContext is "empty", just need to return the JSP path to the form
    return "paypal/index"; // for example
}

// receives the form
@RequestMapping(value = "/payPal2", headers = "Accept=application/json", method = RequestMethod.POST)
public @ResponseBody Payment payByCreditCardPost(@ModelAttribute("orderContext") OrderContext orderContext, Model model) throws Exception {
    // form is submitted, orderContext is set depending on the form entries
}

答案 1 :(得分:-1)

从中重定向到表单的方法,在请求范围中添加OrderContext对象,如下所示:

@RequestMapping(ur_mapping_url)
public String loadForm(Model model){
  model.addAttribute(new OrderContext());
  return "formPage_name";
}