简体   繁体   English

使用Spring MVC表单提交portlet

[英]Form submit portlet with Spring MVC

I'm trying to achieve a Liferay portlet of submit form using spring MVC. 我正在尝试使用spring MVC实现提交表单的Liferay portlet。

The model: 该模型:

package com.model;

public class Person {
    String firstName;
    String middleName;

    public String getFirstName()
    {
        return this.firstName;
    }

    public String getMiddleName()
    {
        return this.middleName;
    }

    public void setFirstName(String firstName)
    {
        this.firstName=firstName;
    }

    public void setMiddleName(String middleName)
    {
        this.middleName=middleName;
    }
}

The controller: 控制器:

package com.controller;

import com.model.Person;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.portlet.ModelAndView;
import org.springframework.web.portlet.bind.annotation.ActionMapping;
import org.springframework.web.portlet.bind.annotation.RenderMapping;

@Controller(value = "MyFirstSpringMVCPortlet")
@RequestMapping("VIEW")
public class MyFirstSpringMVCPortlet {

    @RenderMapping
    public ModelAndView handleRenderRequest() {
        ModelAndView modelAndView = new ModelAndView("welcome");
        modelAndView.addObject("person", new Person());
        modelAndView.addObject("msg", "Hello Spring MVC");
        return modelAndView; 
    }


    @ActionMapping(value = "handleSubmitPerson")
    public void submitPerson(
            @ModelAttribute("person") Person person,
            ActionRequest actionRequest, ActionResponse actionResponse,
            Model model) {
            System.out.println("FirstName= "+person.getFirstName());
            System.out.println("MiddleName= "+person.getMiddleName());
    }


}

View (welcome.jsp) 查看(welcome.jsp)

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<h1>${msg}</h1>
<portlet:defineObjects />
<portlet:actionURL var="submitFormURL" name="handleSubmitPerson"/>
<form:form name="person" method="post" modelAttribute="person" action="<%=submitFormURL.toString() %>">
<br/>
    <table style="margin-left:80px">
        <tbody>
            <tr>
                <td><form:label path="firstName">First Name</form:label></td>
                <td><form:input path="firstName"></form:input></td>
            </tr>
            <tr>
                <td><form:label path="middleName">Middle Name</form:label></td>
                <td><form:input path="middleName"></form:input></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="Submit Form">
                </td>
            </tr>
        </tbody>
    </table>
</form:form>

I built the war with maven and then I deployed the war under apache tomcat of Liferay portal. 我用maven建立了战争,然后我在Liferay门户的apache tomcat下部署了战争。 Until this point everything is working fine without problems. 在此之前一切正常,没有问题。 But when I tried to run the portlet I got in the console an error. 但是当我试图运行portlet时,我在控制台中出错了。 The following stacktrace describes it: 以下stacktrace描述了它:

11:37:15,586 ERROR [RuntimePageImpl-26][render_portlet_jsp:132] null
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'person' available as request attribute
    at org.apache.jsp.WEB_002dINF.jsp.welcome_jsp._jspx_meth_form_005flabel_005f0(welcome_jsp.java:238)
    at org.apache.jsp.WEB_002dINF.jsp.welcome_jsp._jspService(welcome_jsp.java:173)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    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 com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:96)
    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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:605)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:544)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)

It seems that I have something wrong in my controller. 我的控制器似乎有问题。 Can someone help me please to correct the problem? 有人可以帮我解决问题吗?

Which version of Liferay you are using? 您正在使用哪个版本的Liferay?

if it is > 6.2 GA1 如果它是> 6.2 GA1

Then in your liferay-portlet.xml file, please add this attribute and recompile and test again. 然后在liferay-portlet.xml文件中,添加此属性并重新编译并再次测试。

<requires-namespaced-parameters>false</requires-namespaced-parameters>

Liferay adds namespace to the request parameters by default. Liferay默认情况下会将命名空间添加到请求参数中。 You need to disable it. 你需要禁用它。

Take a look to this example,maybe its helpful four you. 看看这个例子,也许它对你有帮助。

You have to use ModelAndView correctly. 您必须正确使用ModelAndView。

Neither BindingResult nor plain target object for bean name available as request attribute BindingResult和bean名称的普通目标对象都不可用作请求属性

Form tag in JSP raises the exception, because there's no "person" attribute in the model. JSP中的表单标记引发了异常,因为模型中没有“person”属性。 You have to include the instance of Person class in the model. 您必须在模型中包含Person类的实例。 There're several ways how to achieve it. 有几种方法可以实现它。 Method annotated with @ModelAttribute annotation is probably the most convenient. 使用@ModelAttribute注释注释的方法可能是最方便的。

I suggest to add the following method to the controller: 我建议将以下方法添加到控制器:

@ModelAttribute("person")
public Person getPerson() {
    return new Person();
}

Or you can modify the render method (I also removed the unused parameters from the signature): 或者您可以修改渲染方法(我还从签名中删除了未使用的参数):

@RenderMapping
public ModelAndView handleRenderRequest() {
    ModelAndView modelAndView = new ModelAndView("welcome");
    modelAndView.addObject("person", new Person());
    modelAndView.addObject("msg", "Hello Spring MVC");
    return modelAndView; 
}

You are trying to obtain "person" model attribute in submitPerson method and you are trying to use "person" model attribute in your JSP . 您正在尝试在submitPerson方法中获取“person”模型属性,并且您尝试在JSP使用“person”模型属性。 However, you didn't set that model attribute previously. 但是,您之前未设置该模型属性。 So set your person model attribute first in like handleRenderRequest method: 因此,首先在handleRenderRequest方法中设置您的人物模型属性:

ModelAndView modelAndView = new ModelAndView("welcome");
modelAndView.addObject("person", new Person());

This is because you are binding "person" object in your jsp, but you are not passing anything for variable "person" from controller. 这是因为你在jsp中绑定了“person”对象,但你没有从控制器传递任何变量“person”。 And that's why render is unable to find that object in scope and throws an exception. 这就是为什么渲染无法在范围内找到该对象并抛出异常的原因。

Add below line of code in your controller method and it'll work. 在控制器方法中添加以下代码行,它将起作用。

mv.addObject("person", new Person()) // Note : you must use same name in jsp page as defined in first argument

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM