Spring MVC @ModelAttribute返回“错误请求”错误400

时间:2018-02-09 10:51:04

标签: java spring jsp model-view-controller

亲爱的Spring java专业人士, 我的问题: 我正在尝试发送POST请求,但是我收到“错误请求400”错误。 我在这里找到了一个类似的问题:Spring MVC @ModelAttribute method returns "Bad request" 400,但是这个问题对我没有帮助。

也许有人可以帮助我。

这是我的MainControler.java的一部分

@Controller
public class OverviewController {

    private static final Logger logger = Logger
        .getLogger(OverviewController.class);

    public OverviewController() {
        System.out.println("ExperimentController()");
    }

    @Autowired
    private ExperimentService experimentService;

    @Autowired
    private TestService testservice;    

    @RequestMapping(value = "/Testbereich/Versuch/Test")
    public ModelAndView newExperimentTest(ModelAndView model, @ModelAttribute("experiment") Experiment experiment) throws IOException{
         Test test = new Test();
         model.addObject("test", test);
         model.addObject("experiment", experiment);
         model.setViewName("TestView");
         return model;
    }

    @RequestMapping(value = "/Testbereich/Versuch/saveTest", method = RequestMethod.POST)
    public ModelAndView saveTest(@ModelAttribute("test") Test test) {

         testservice.addTest(test);
         return new ModelAndView("redirect:/Uebersicht/Experiment");
    }
}

还有我的experiment.java和test.java实体

@Entity
@Table(name = "Experiment")
public class Experiment implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 3291761748164983832L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int experiment_id;

    @Column
    private String reader_type;

    @Column
    private String antenne_A;

    @Column
    private String antenne_B;

    @Column
    private String antenne_C;

    @Column
    private String antenne_D;

    @Column
    private String antenne_E;

    @Column
    private String antenne_F;

    @Column
    private String antenne_G;

    @Column
    private String antenne_H;

    @Column
    private String antenne_I;


    @Column
    private String fill_hight;

    @Column
    private int angle;

    @Column
    private String additional;

    @OneToMany(mappedBy="experiment")
    private Set<Test> tests;

    public int getExperiment_id() {
        return experiment_id;
    }

    public void setExperiment_id(int experiment_id) {
        this.experiment_id = experiment_id;
    }

    public String getReader_type() {
        return reader_type;
    }

    public void setReader_type(String reader_type) {
        this.reader_type = reader_type;
    }

    public String getFill_hight() {
        return fill_hight;
    }

    public void setFill_hight(String fill_hight) {
        this.fill_hight = fill_hight;
    }

    public int getAngle() {
        return angle;
    }

    public void setAngle(int angle) {
        this.angle = angle;
    }

    public String getAdditional() {
        return additional;
    }

    public void setAdditional(String additional) {
        this.additional = additional;
    }

    public Set<Test> getTests() {
        return tests;
    }

    public void setTests(Set<Test> tests) {
        this.tests = tests;
    }

    public String getAntenne_A() {
        return antenne_A;
    }

    public void setAntenne_A(String antenne_A) {
        this.antenne_A = antenne_A;
    }

    public String getAntenne_B() {
        return antenne_B;
    }

    public void setAntenne_B(String antenne_B) {
        this.antenne_B = antenne_B;
    }

    public String getAntenne_C() {
        return antenne_C;
    }

    public void setAntenne_C(String antenne_C) {
        this.antenne_C = antenne_C;
    }

    public String getAntenne_D() {
        return antenne_D;
    }

    public void setAntenne_D(String antenne_D) {
        this.antenne_D = antenne_D;
    }

    public String getAntenne_E() {
        return antenne_E;
    }

    public void setAntenne_E(String antenne_E) {
        this.antenne_E = antenne_E;
    }

    public String getAntenne_F() {
        return antenne_F;
    }

    public void setAntenne_F(String antenne_F) {
        this.antenne_F = antenne_F;
    }

    public String getAntenne_G() {
        return antenne_G;
    }

    public void setAntenne_G(String antenne_G) {
        this.antenne_G = antenne_G;
    }

    public String getAntenne_H() {
        return antenne_H;
    }

    public void setAntenne_H(String antenne_H) {
        this.antenne_H = antenne_H;
    }

    public String getAntenne_I() {
        return antenne_I;
    }

    public void setAntenne_I(String antenne_I) {
        this.antenne_I = antenne_I;
    }

}

测试实体

@Entity
public class Test implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -2345940545223928492L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int test_id;

    @Column
    private int uid_count;

    @Column
    private int speed;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date test_stop;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private Date test_start;

    @ManyToOne
    @JoinColumn(name="experiment_id", nullable=false)
    private Experiment experiment;


    public int getTest_id() {
        return test_id;
    }

    public void setTest_id(int test_id) {
        this.test_id = test_id;
    }

    public int getUid_count() {
        return uid_count;
    }

    public void setUid_count(int uid_count) {
        this.uid_count = uid_count;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public Date getTest_stop() {
        return test_stop;
    }

    public void setTest_stop(Date test_stop) {
        this.test_stop = test_stop;
    }

    public Date getTest_start() {
        return test_start;
    }

    public void setTest_start(Date test_start) {
        this.test_start = test_start;
    }

    public Experiment getExperiment() {
        return experiment;
    }

    public void setExperiment(Experiment experiment) {
        this.experiment = experiment;
    }

}

我的TestView.jsp的相关部分

    <form:form method="POST" action="saveTest" modelAttribute="test">
    <div class="container">

        <br>
        <br>

        <div class="row">
            <div class="col-lg-12">
                <div class="page-header">
                    <h1>Testbereich</h1>
                    <p class="lead">Erstellen sie ein neuen Test</p>
                </div>
            </div>
        </div>

        <br>
        <br>

        <div class="row">
            <div class="col-lg-5">

                <form:hidden path="test_id"/>
                <form:hidden path="experiment" value="${experiment}"/>

                <div class="form-group">
                    <div class="row">
                        <div class="col-3">
                            <input  type="button" class="btn btn-primary" id="input-start" value="Test Starten" onclick="clickStartButton()">
                        </div>
                        <div class="col-8 offset-1">
                            <form:input class="form-control" path="test_start" id="start_value" value="" disabled="true"></form:input>                              
                        </div>
                    </div>  
                </div>

                <div class="form-group">
                    <div class="row">
                        <div class="col-3">
                            <input  type="button" class="btn btn-primary" id="input-stop" value="Test Stoppen" onclick="clickStopButton()"></input>
                        </div>
                        <div class="col-8 offset-1">
                            <form:input class="form-control" path="test_stop" id="stop_value" value="" disabled="true"></form:input>
                        </div>

                    </div>  
                </div>

                <div class="form-group">
                    <label for="input-uidCount">Anzahl der erfassten UIDs</label>
                    <form:input class="form-control" path="uid_count" id="input-uidCount"/>
                </div>

                <div class="form-group">
                    <label for="input-speed">Geschwindigkeit des Testfahrzeugs in km/h</label>
                    <form:input class="form-control" path="speed" id="input-speed"/>
                </div>

                <div class="form-group">
                    <input type="submit" class="btn btn-primary" value="Test Speichern"/>
                </div>
            </div>         
        </div>
        <div class="col-lg-5 offset-lg-1">

        </div>
    </div>
</form:form>

<script type="text/javascript">

    function clickStartButton() {
        var datetime
        datetime = new Date().toISOString().slice(0, 19).replace('T', ' ');
        document.getElementById("start_value").value = datetime;
    }

    function clickStopButton() {
        var datetime
        datetime = new Date().toISOString().slice(0, 19).replace('T', ' ');
        document.getElementById("stop_value").value = datetime;
    }


</script>

我希望我已经充分描述了这个问题。如果遗漏了什么,请写信给我。跟我一起,这是我的第一个问题。

2 个答案:

答案 0 :(得分:0)

知道实际的Field Error问题试试这个

BindingResult bindingResult

之后添加 @ModelAttribute
@RequestMapping(value = "/Testbereich/Versuch/saveTest", method = RequestMethod.POST)
public ModelAndView saveTest(@ModelAttribute("test") Test test, BindingResult bindingResult) {

for( FieldError fieldError : bindingResult.getFieldErrors() )
    System.out.println(fieldError.getField() +" : "+fieldError.getDefaultMessage());

     testservice.addTest(test);
     return new ModelAndView("redirect:/Uebersicht/Experiment");
}

答案 1 :(得分:0)

错误请求是由于此部分引起的绑定错误

<form:hidden path="experiment" value="${experiment}"/>

Spring MVC使用PropertyEditor或Converter策略将对象类型(即Experiment)转换为String,以便在表单中使用该值。

它还使用另一个Converter将表单上的String参数值转换为model属性上的object字段。您需要使用Web数据绑定器注册转换器。否则绑定到像experimentId这样的简单属性并查找控制器中的对象

1)定义ExperimentToStringConverter

   public class ExperimentToStringConverter implements  Converter<Experiment,String>{

      public String convert(Experiment experiment){
         return String.valueOf(experiment.getExperimentId());
      }
  }

或者覆盖实验中的toString()方法

 public String toString(){
      return String.valueOf(experimentId);
 }

这依赖于使用toString()方法的默认注册ObjectToStringConverter

2)定义StringToExperimentService

 public class StringToExperimentService implements Converter<String,Experiment>{
    public Experiment convert(String text){
       //lookup Experiment probably using  repository
    }
}

3)使用Spring MVC基础设施注册转换器

    @Configuration
    @EnableWebMvc
    public class ConsoleConfiguration extends WebMvcConfigurerAdapter{
       public void addFormatters(final FormatterRegistry registry) {
          super.addFormatters(registry);
          registry.addConverter(new ExperimentToStringConverter());
          registry.addConverter(new StringToExperimentConverter());
       }
    }

如果您使用的是xml配置,则可以按如下方式注册转换器

<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="example.ExperimentToStringConverter"/>
            <bean class="example.StringToExperimentConverter"/>
        </list>
    </property>
</bean>

另外,如同其他答案一样,您需要收集所有绑定和验证错误,以便您可以向用户报告

@RequestMapping(value = "/Testbereich/Versuch/saveTest", method = RequestMethod.POST)
public ModelAndView saveTest(@ModelAttribute("test") Test test, BindingResult result) {
   if(result.hasErrors()){
      return new ModelAndView("TestView");
   }
   testservice.addTest(test);
   return new ModelAndView("redirect:/Uebersicht/Experiment");
 } 

然后将表单:错误添加到表单字段

 <div class="col-8 offset-1">
    <form:input class="form-control" path="test_start" id="start_value" value="" disabled="true"></form:input>    
    <form:errors path="test_start"/>                          
</div>