2017-07-07 74 views
2

下午好,Spring MVC:創建新實體記錄時,客戶端發送的請求在語法上不正確

我是Spring MVC的新手。我在運行我的項目時遇到以下錯誤「客戶端發送的請求在語法上不正確。」

我的項目有兩個實體,團隊和國家有一個ManyToOne關係。這兩個實體都映射在mysql數據庫中創建的表。

我只用Team實體啓動了項目,併成功創建了我的類(DAO,控制器,服務等)和jsp來創建新的團隊。

現在,我創建了類Country來關聯兩個實體,並且在「add-team-form.jsp」中添加了一個下拉列表來選擇新團隊的國家。此頁面正確顯示(所有國家都顯示在下拉列表中),但是,當我單擊「提交」創建新團隊時,我收到錯誤「客戶端發送的請求在語法上不正確。」

你能幫我找出我的錯誤嗎?我猜這是在「add-team-form.jsp」中。

1 - 實體團隊:

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

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Integer id; 

@Column(name = "name", length = 40, nullable = false) 
private String name; 

@Column(name = "rating", length = 6, nullable = false) 
private Integer rating; 

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "id_country", nullable = false) 
private Country country; 


public Integer getId() { 
    return id; 
} 
public void setId(Integer id) { 
    this.id = id; 
} 
public String getName() { 
    return name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
public Integer getRating() { 
    return rating; 
} 
public void setRating(Integer rating) { 
    this.rating = rating; 
} 
public Country getCountry() { 
    return country; 
} 
public void setCountry(Country country) { 
    this.country = country; 
} 
} 

2 - 實體國家:

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

@Id 
@Column(name= "id_country", length = 6) 
private String idCountry; 

@Column(name = "name", length = 255, nullable = false) 
private String name; 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "country") 
private List<Team> teams; 


public String getIdCountry() { 
    return idCountry; 
} 

public void setIdCountry(String idCountry) { 
    this.idCountry = idCountry; 
} 

public String getName() { 
    return name; 
} 

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

我的團隊DAO

@Repository 
public class TeamDAOImpl implements TeamDAO { 

@Autowired 
private SessionFactory sessionFactory; 

private Session getCurrentSession() { 
    return sessionFactory.getCurrentSession(); 
} 

@Override 
public void addTeam(Team team) { 

    getCurrentSession().save(team); 
} 
} 

我的團隊服務

@Service 
@Transactional 
public class TeamServiceImpl implements TeamService { 

@Autowired 
private TeamDAO teamDAO; 

public void addTeam(Team team) { 
    teamDAO.addTeam(team);  
} 

我的團隊控制器

@Controller 
@RequestMapping(value="/team") 
public class TeamController { 

@Autowired 
private TeamService teamService; 

@Autowired 
private FilterService filterService; 

@RequestMapping(value="/add", method=RequestMethod.GET) 
public ModelAndView addTeamPage() { 
    ModelAndView modelAndView = new ModelAndView("add-team-form"); 
    modelAndView.addObject("team", new Team()); 

    return modelAndView; 
} 

@RequestMapping(value="/add", method=RequestMethod.POST) 
public ModelAndView addingTeam(@ModelAttribute Team team) { 

    ModelAndView modelAndView = new ModelAndView("home"); 

    teamService.addTeam(team); 

    String message = "Team was successfully added."; 
    modelAndView.addObject("message", message); 

    return modelAndView; 
} 

@ModelAttribute("countryList") 
public Map<String, String> getCountryList(){ 

    Map<String, String> countryList = filterService.getCountries(); 
    return countryList; 
    } 

... 
} 

我的「附加團隊form.jsp」

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %> 
<?xml version="1.0" encoding="ISO-8859-1" ?> 

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> 
<title>Add team page</title> 
</head> 
<body> 
    <h1>Add team page</h1> 

<form:form method="POST" 
     modelAttribute="team" 
     action="${pageContext.request.contextPath}/team/add.html"> 
<table> 
    <tbody> 
    <tr> 
     <td>Name:</td> 
     <td><form:input path="name" /></td> 
    </tr> 
    <tr> 
     <td>Rating:</td> 
     <td><form:input path="rating" /></td> 
    </tr> 
    <tr> 
    <td><label>Country</label></td> 
    <td> 
     <form:select path="country.idCountry"> 
      <form:options items="${countryList}" /> 
     </form:select>  
    </td> 
    <tr> 
     <td><input type="submit" value="Add" /></td> 
     <td></td> 
    </tr> 

</tbody> 
</table> 
</form:form> 

</body> 
</html> 

有在Eclipse的控制檯顯示沒有錯誤,但這裏是錯誤IM從瀏覽器接收:

HTTP Status 400 - 

type Status report 

message 

description The request sent by the client was syntactically incorrect. 
Apache Tomcat/7.0.47 
+0

的更多信息,你能否告訴我們完整的堆棧跟蹤? –

+0

@TanmayDelhikar我用瀏覽器收到的錯誤更新了問題,在eclipse的控制檯中沒有顯示錯誤。 – MiguelDuque

+0

打開日誌到DEBUG;如果使用Boot,這裏是[how](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html)。如果瀏覽器收到錯誤,則還會在服務器端打印一個錯誤。 –

回答

1

我在這裏可以看到一些問題 - 您正在發佈add/team/add.html,而不是擊中您的帖子處理程序。在發佈到同一端點時,您不需要action屬性;

<form:form method="POST" modelAttribute="team" > 

其次你被注入國家的地圖,所以這些都是ID /顯示值這對於鍵/值對和值綁定到一個字符串字段的偉大工程。在這種情況下,Spring試圖將你的國家ID(字符串)綁定到team.country(Country)字段,該字段將失敗。爲了幫助Spring出來,你需要一個數據綁定器;在你的控制器中添加;

@InitBinder 
public void initBinder (WebDataBinder binder) { 
    binder.registerCustomEditor(Country.class, new CountryEditor()); 
} 

並創建屬性編輯器類;

public class CountryEditor extends PropertyEditorSupport { 
    @Override 
    public void setValue(Object value) { 
     super.setValue(value); 
    } 

    public String getAsText() { 
     if (getValue() == null) return null; 
     return ((Country) getValue()).getName(); 
    }; 

    public void setAsText(String text) throws IllegalArgumentException { 
     if (text != null) { 
      Country country = // something like filterService.getCountryById(text); 
      setValue(country); 
     } 
    }; 
} 

有一個在Spring documentation

+0

謝謝你的幫助! – MiguelDuque

-1

如果參數丟失或者格式不同,並且無法轉換爲預期類型,則通常會收到錯誤。檢查值將被傳遞給Team對象。您可以記錄請求和響應,或者將日誌級別設置爲「DEBUG」,這將在日誌中顯示確切的錯誤。

相關問題