出错部分是学习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("test@gmail.com"); 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,这样可以转换模式。