【问题标题】:Null parameters when sending post to Spring Controller将帖子发送到 Spring Controller 时为空参数
【发布时间】:2016-04-30 15:08:22
【问题描述】:

我已经尝试解决这个问题很长时间了,但我看不出我的配置有什么问题。

我想做的是创建一个新的“元数据”对象。该对象具有以下域类:

package domain;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.hibernate.validator.constraints.NotBlank;

@Entity
@Access(AccessType.PROPERTY)
public class Metadata extends DomainEntity{

    private String name;

    //Relationship

    private Collection<Question> questions;

    public Metadata() {
        super();
        questions = new ArrayList<Question>();
    }

    @Valid
    @NotBlank
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Valid
    @NotNull
    @ManyToMany(mappedBy = "metadata")
    public Collection<Question> getQuestions() {
        return questions;
    }

    public void setQuestions(Collection<Question> questions) {
        this.questions = questions;
    }




}

所以我有一个按钮,该按钮可以转到带有空输入属性“名称”的创建页面(其余属性为空或由 spring 自动生成)。创建视图如下:

<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%@taglib prefix="jstl" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@taglib prefix="security"
    uri="http://www.springframework.org/security/tags"%>
<%@taglib prefix="display" uri="http://displaytag.sf.net"%>
<%@ taglib prefix="acme" tagdir="/WEB-INF/tags"%>




<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="well well-sm">
                <form:form class="form-horizontal" method="POST"
                    action="metadata/edit.do" modelAttribute="metadata"
                    enctype="multipart/form-data">

                    <form:hidden path="id" />
                    <form:hidden path="version" />
                    <form:hidden path="questions" />

                    <fieldset>

                        <!-- Name -->
                        <div class="form-group">
                            <form:label path="name" class="col-md-3 control-label" for="name">
                                <spring:message code="metadata.name" />
                            </form:label>
                            <div class="col-md-6">
                                <form:input path="name" id="name" name="name" type="text"
                                    class="form-control" />
                            </div>
                            <form:errors path="name" cssClass="error" />
                        </div>


                        <!-- Form actions -->
                        <div class="form-group">
                            <div class="col-md-12 text-center">
                                <input type="submit" name="save" class="btn btn-primary btn-lg"
                                    value="<spring:message code="metadata.save" />" />
<%--                                <jstl:if test="${!create}"> --%>
<!--                                    <a class="btn btn-primary btn-lg" data-toggle="modal" -->
<%--                                        data-target="#basicModal"><spring:message --%>
<%--                                            code="metadata.delete" /></a> --%>
<!--                                    <div class="modal fade" id="basicModal" tabindex="-1" -->
<!--                                        role="dialog" aria-labelledby="basicModal" aria-hidden="true"> -->
<!--                                        <div class="modal-dialog"> -->
<!--                                            <div class="modal-content"> -->
<!--                                                <div class="modal-header"> -->
<!--                                                    <button type="button" class="close" data-dismiss="modal" -->
<!--                                                        aria-hidden="true">&times;</button> -->
<!--                                                    <h4 class="modal-title" id="myModalLabel"> -->
<%--                                                        <spring:message code="metadata.confirm.title" /> --%>
<!--                                                    </h4> -->
<!--                                                </div> -->
<!--                                                <div class="modal-body"> -->
<!--                                                    <h3> -->
<%--                                                        <spring:message code="metadata.confirm.body" /> --%>
<!--                                                    </h3> -->
<!--                                                </div> -->
<!--                                                <div class="modal-footer"> -->
<!--                                                    <button type="submit" name="delete" class="btn btn-default" -->
<!--                                                        onclick="history.back()"> -->
<%--                                                        <spring:message code="metadata.confirm.yes" /> --%>
<!--                                                    </button> -->
<!--                                                    <button type="button" class="btn btn-primary" -->
<!--                                                        data-dismiss="modal"> -->
<%--                                                        <spring:message code="metadata.confirm.no" /> --%>
<!--                                                    </button> -->
<!--                                                </div> -->
<!--                                            </div> -->
<!--                                        </div> -->
<!--                                    </div> -->
<%--                                </jstl:if> --%>
                                <a href="metadata/list.do"><input type="button"
                                    class="btn btn-primary btn-lg"
                                    value="<spring:message code="metadata.cancel"/>" id="cancelar"
                                    name="cancelar"
                                    onclick="self.location.href = metadata/list.do" /></a>
                            </div>
                        </div>
                    </fieldset>
                </form:form>
            </div>
        </div>
    </div>
</div>

最后,由于 BindingProvider 导致失败的控制器类出现错误,因为元数据对象的属性“名称”不能为空:

package controllers;

import java.util.ArrayList;
import java.util.Collection;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import services.MetadataService;
import domain.Metadata;
import domain.Question;


@Controller
@RequestMapping("/metadata")
public class MetadataController {


    // Services ----------------------------------------------------------------

    @Autowired
    private MetadataService metadataService;


    // Constructor
    // ---------------------------------------------------------------
    public MetadataController() {
        super();
    }

    // Listing
    // -------------------------------------------------------------------

    @RequestMapping("/list")
    public ModelAndView list() {
        ModelAndView result;
        String uri = "metadata/list";
        String requestURI = "metadata/list.do";
        Collection<Metadata> metadatas = metadataService.findAll();
        result = createListModelAndView(requestURI, metadatas, uri);

        return result;
    }

    // Creation
        // ------------------------------------------------------------------
        @RequestMapping(value = "/create", method = RequestMethod.GET)
        public ModelAndView create() {

            ModelAndView result;

            Metadata metadata = metadataService.create();

            result = createCreateModelAndView(metadata);
            return result;
        }

        // Edition
        // -------------------------------------------------------------------

        @RequestMapping(value = "/edit", method = RequestMethod.GET)
        public ModelAndView edit(@RequestParam int metadataId) {
            ModelAndView result;
            Metadata metadata = metadataService.findOne(metadataId);

            result = createEditModelAndView(metadata);

            return result;
        }

        @RequestMapping(value = "/edit", method = RequestMethod.POST)
        public ModelAndView save(@Valid Metadata metadata, BindingResult binding,
                RedirectAttributes redirect) {
            ModelAndView result;

            if (binding.hasErrors()) {
                if (metadata.getId() == 0) {
                    result = createEditModelAndView(metadata, "metadata.commit.error");
                } else {
                    result = createCreateModelAndView(metadata, "metadata.commit.error");
                }
            } else {
                try {
                    metadataService.save(metadata);
                    result = new ModelAndView("redirect:list.do");
                } catch (Throwable oops) {
                    if (metadata.getId() == 0) {
                        result = createEditModelAndView(metadata, "metadata.commit.error");
                    } else {
                        result = createCreateModelAndView(metadata, "metadata.commit.error");
                    }

                }

            }

            return result;
        }

//      @RequestMapping(value = "/edit", method = RequestMethod.POST, params = "delete")
//      public ModelAndView delete(@ModelAttribute Metadata metadata,
//              BindingResult bindingResult, RedirectAttributes redirect) {
//          ModelAndView result;
//
//          try {
//              redirect.addFlashAttribute("successMessage", "metadata.deleteSuccess");
//              metadataService.delete(metadata);
//              result = new ModelAndView("redirect:list.do");
//          } catch (Throwable oops) {
//              if (oops.getMessage() == "Error") {
//                  result = createEditModelAndView(metadata, "metadata.error");
//              } else {
//                  result = createEditModelAndView(metadata, "metadata.commit.error");
//              }
//          }
//          return result;
//      }



    // Other bussiness method

        protected ModelAndView createEditModelAndView(Metadata metadata) {
            assert metadata != null;

            ModelAndView result;

            result = createEditModelAndView(metadata, null);

            return result;
        }

        protected ModelAndView createCreateModelAndView(Metadata metadata) {
            assert metadata != null;

            ModelAndView result;

            result = createCreateModelAndView(metadata, null);
            return result;
        }

        protected ModelAndView createEditModelAndView(Metadata metadata,
                String message) {
            assert metadata != null;
            Collection<Question> questions = new ArrayList<Question>();
            ModelAndView result;
            result = new ModelAndView("metadata/edit");
            result.addObject("questions", questions);
            result.addObject("metadata", metadata);

            return result;
        }

        protected ModelAndView createCreateModelAndView(Metadata metadata,
                String message) {
            assert metadata != null;
            Collection<Question> questions = new ArrayList<Question>();
            ModelAndView result;
            result = new ModelAndView("metadata/create");
            result.addObject("questions", questions);
            result.addObject("create", true);
            result.addObject("metadata", metadata);

            return result;
        }

        protected ModelAndView createListModelAndView(String requestURI,
                Collection<Metadata> metadatas, String uri) {
            ModelAndView result;

            result = new ModelAndView(uri);
            result.addObject("metadatas", metadatas);
            result.addObject("requestURI", requestURI);

            return result;
        }



}

看了几天后,我无法通过提交按钮将我想要的值发送到控制器,我不知道该怎么做。没有日志错误。它只是返回创建页面说“名称”不能为空。

【问题讨论】:

    标签: java spring jsp spring-mvc model-view-controller


    【解决方案1】:
    public ModelAndView save(@Valid Metadata metadata 
    

    我认为您在上面的行中缺少@ModelAttribute annotation。您可以将其用作 当您想从请求中绑定数据并将其隐式添加到模型时的参数。

    所以将您的保存方法更改为
    public ModelAndView save(@ModelAttribute("metadata") @Valid Metadata metadata 如果您可以发布结果,这应该可以正常工作。

    【讨论】:

      【解决方案2】:

      问题是我使用enctype=multipart...,而我没有发送任何二进制数据。

      这似乎在Spring 中产生了一些冲突。删除 enctype 并让 Spring 使用默认设置解决了问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-14
        • 2019-07-25
        • 1970-01-01
        • 2019-01-15
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        相关资源
        最近更新 更多