錯誤400-The request sent by the client was syntactically incorrect
出錯部分是學習SpringMVC 時學習https://my.oschina.net/gaussik/blog/640164,在添加博客文章部分出現了這個問題。
The request sent by the client was syntactically incorrect 說的意思是:由客戶端發送的請求是語法上是不正確的。
上網找了很多資料,大部分都是說前端jsp頁面的控件名稱(name)和controller中接收的參數名稱不一致,檢查以後確實存在這個問題,修改以後還是沒有解決,這說明別的地方還存在問題。
網上還有一種說法,就是提交表單數據類型與model不匹配,或方法參數順序錯誤,這主要是json時會出現這個問題,但我並沒有用到json,是直接用類的,所以照著修改了以後還是沒有解決。(詳見http://cuisuqiang.iteye.com/blog/2054234)
再有一種就是form表單中有日期,Spring不知道該如何轉換,如要在實體類的日期屬性上加@DateTimeFormat(pattern="yyyy-MM-dd")註解,添加以後確實解決了。
public class BlogEntity { private int id; private String title; private UserEntity userByUserId; private String context; @DateTimeFormat(pattern="yyyy-MM-dd") private Date pubDate;
P.S.在修改這個bug的過程中,真的是學到了。這個部分的前端可以獲取值,但到controller時就沒有接收到了。
@RequestMapping(value = "/admin/blogs/addP", method = RequestMethod.POST) public String addBlogPost(@ModelAttribute("blog") BlogEntity blogEntity){ //打印博客標題 System.out.println(blogEntity.getTitle()); //打印博客作者 System.out.println(blogEntity.getUserByUserId().getNickname()); blogRepository.saveAndFlush(blogEntity);return "redirect:/admin/blogs"; }
這是controller的部分
<form:form action="/admin/blogs/addP" method="post" commandName="blog" role="form"> <div class="form-group"> <%--@declare id="title"--%><label for="title">Title:</label> <input type="text" name="title" id="title" class="form-control" placeholder="Enter Title:"> </div> <div class="form-group"> <%--@declare id="userbyuserid.id"--%><label for="userByUserId.id">Author:</label> <select class="form-control" id="userByUserId.id" name="userByUserId.id"> <c:forEach items="${userList}" var="user"> <option value="${user.id}">${user.nickname},${user.firstName} ${user.lastName}</option> </c:forEach> </select> </div> <div class="form-group"> <%--@declare id="context"--%><label for="context">Content:</label> <textarea class="form-control" id="context" name="context" rows="3" placeholder="Please Input Content"></textarea> </div> <div class="form-group"> <%--@declare id="pubdate"--%><label for="pubDate">Publish Date:</label> <input type="date" class="form-control" id="pubDate" name="pubDate"> </div> <div class="form-group"> <button type="submit" class="btn btn-sm btn-success">提交</button> </div> </form:form>
這是jsp的部分。
package com.euphe.model; import org.springframework.format.annotation.DateTimeFormat; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "blog", schema = "blog") public class BlogEntity { private int id; private String title; private UserEntity userByUserId; private String context; @DateTimeFormat(pattern="yyyy-MM-dd") private Date pubDate; @Id @Column(name = "id", nullable = false) public int getId() { return id; } public void setId(int id) { this.id = id; } @Basic @Column(name = "title", nullable = false, length = 100) public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @ManyToOne @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false) public UserEntity getUserByUserId() { return userByUserId; } public void setUserByUserId(UserEntity userByUserId) { this.userByUserId = userByUserId; } @Basic @Column(name = "context", nullable = true, length = 255) public String getContext() { return context; } public void setContext(String context) { this.context = context; } @Basic @Column(name = "pub_date", nullable = false) public Date getPubDate() { return pubDate; } public void setPubDate(Date pubDate) { this.pubDate = pubDate; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BlogEntity that = (BlogEntity) o; if (id != that.id) return false; if (title != null ? !title.equals(that.title) : that.title != null) return false; if (context != null ? !context.equals(that.context) : that.context != null) return false; if (pubDate != null ? !pubDate.equals(that.pubDate) : that.pubDate != null) return false; return true; } @Override public int hashCode() { int result = id; result = 31 * result + (title != null ? title.hashCode() : 0); result = 31 * result + (context != null ? context.hashCode() : 0); result = 31 * result + (pubDate != null ? pubDate.hashCode() : 0); return result; } }
這是entity部分,即類的定義
打斷點都打在entity上,發現沒能接收的值只有pubDate,所以一步一步地往下進行調試,這時因為是嵌套的框架,所以會進入到框架內的代碼。不要慌張,慢慢往下走會發現throws exception了,這時可以發現是類型轉換出了問題,前端傳入的是string,但後端接收的是date類型,其中沒辦法轉換。
其實還有一種方法,可以類似這樣(http://www.mkyong.com/spring-mvc/spring-mvc-form-handling-example/)
// save or update user // 1. @ModelAttribute bind form value // 2. @Validated form validator // 3. RedirectAttributes for flash value @RequestMapping(value = "/users", method = RequestMethod.POST) public String saveOrUpdateUser(@ModelAttribute("userForm") @Validated User user, BindingResult result, Model model, final RedirectAttributes redirectAttributes) { logger.debug("saveOrUpdateUser() : {}", user); if (result.hasErrors()) { populateDefaultModel(model); return "users/userform"; } else { // Add message to flash scope redirectAttributes.addFlashAttribute("css", "success"); if(user.isNew()){ redirectAttributes.addFlashAttribute("msg", "User added successfully!"); }else{ redirectAttributes.addFlashAttribute("msg", "User updated successfully!"); } userService.saveOrUpdate(user); // POST/REDIRECT/GET return "redirect:/users/" + user.getId(); // POST/FORWARD/GET // return "user/list"; } } // show add user form @RequestMapping(value = "/users/add", method = RequestMethod.GET) public String showAddUserForm(Model model) { logger.debug("showAddUserForm()"); User user = new User(); // set default value user.setName("mkyong123"); user.setEmail("[email protected]"); user.setAddress("abc 88"); user.setNewsletter(true); user.setSex("M"); user.setFramework(new ArrayList<String>(Arrays.asList("Spring MVC", "GWT"))); user.setSkill(new ArrayList<String>(Arrays.asList("Spring", "Grails", "Groovy"))); user.setCountry("SG"); user.setNumber(2); model.addAttribute("userForm", user); populateDefaultModel(model); return "users/userform"; }
將一個entity打開,一個一個set,這樣可以轉換模式。
錯誤400-The request sent by the client was syntactically incorrect