Spring-MVC:为 posting/retreival 个对象创建 restful 控制器
Spring-MVC : Creating restful controller for posting/retreival of Objects
我正在开发一个 Android 应用程序,我想用它连接到一个基于 Spring-MVC 的 Web 应用程序。目前我正在为 webapp 构建一个 restful 控制器。我尝试通过 Android 连接到控制器方法以保存我正在传递的对象。在数据库中创建了一个空行(带有 Id ofcourse)。我可以使用一些帮助来了解如何发送 Java 可以持久化的对象,以及如何检索 object/s。这是我目前所拥有的:
当前控制器:
@RequestMapping(value = "/restaurant/add",method = RequestMethod.POST)
@ResponseStatus( HttpStatus.CREATED )
@ResponseBody
public String addRestaurantWebView(Restaurant restaurant){
System.out.println("Restaurant details are"+restaurant.getRestaurantName());
return "true";
}
Spring bean :
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:ref bean="jsonMessageConverter"/>
</beans:property>
</beans:bean>
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
餐厅实体:
@Entity
@Table(name="restaurant")
public class Restaurant implements UserDetails{
private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_RESTO");
private static final String emailRegexp = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$";
@Id
@Column(name="restaurantid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "restaurant_seq_gen")
@SequenceGenerator(name = "restaurant_seq_gen",sequenceName = "restaurant_seq")
private int restaurantId;
@Column(name = "restaurantname")
private String restaurantName;
@Column(name = "restaurantemail")
private String restaurantEmail;
@Column(name = "restaurantaddress")
private String restaurantAddress;
@Column(name = "password")
private String password;
@Column(name = "postleitzahl")
private int postLeitZahl;
@Column(name = "phonenumber")
private int phoneNumber;
@Column(name = "speciality")
private String restaurantSpeciality;
@Column(name = "city")
private String city;
@Transient
private List<GrantedAuthority> authorities;
@OneToMany(mappedBy = "restaurantforrating", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
private Set<Rating> ratingSet = new HashSet<>();
public Set<Rating> getRatingSet(){return this.ratingSet;}
public void setRatingSet(Set<Rating> ratingSet){
this.ratingSet = ratingSet;
}
@OneToMany(mappedBy = "restaurantmenucard", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
private Set<MenuCard> menuCardSet = new HashSet<>();
public Set<MenuCard> getMenuCardSet(){
return this.menuCardSet;
}
public void setMenuCardSet(Set<MenuCard> menuCardSet){
this.menuCardSet = menuCardSet;
}
Android 发送对象的代码:
字符串url = "http://192.168.178.40:8080/restaurant/add";
@Override
public void addRestaurant(Restaurant restaurant) {
Log.d("Restaurant Name",restaurant.getRestaurantName());
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON);
// HttpEntity entity = new HttpEntity(restaurant,headers);
//ResponseEntity<String> out = restTemplate.exchange(url, HttpMethod.POST,entity,String.class);
String response = restTemplate.postForObject(url,restaurant,String.class);
Log.d(response,"Response from webserver is");
}
});
thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
}
Android 错误日志:
02-19 10:01:14.099 2266-2285/com.example.myapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-166
Process: com.example.myapp, PID: 2266
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:76)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:524)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:481)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:317)
at com.example.myapp.RestaurantServiceImpl.run(RestaurantServiceImpl.java:32)
at java.lang.Thread.run(Thread.java:818)
02-19 10:01:14.826 2266-2266/com.example.myapp I/Choreographer﹕ Skipped 41 frames! The application may be doing too much work on its main thread.
这就是目前的情况。现在真的很烦人,因为我不知道也无法在网上找到我做错了什么。服务器中的 Java class 是否需要与 Android 中的完全匹配,因为 Android Java class 中没有映射。
尝试向您的 spring 控制器添加 @RequestBody 注释。
@RequestMapping(value = "/restaurant/add",method = RequestMethod.POST)
@ResponseBody
public String addRestaurantWebView(@RequestBody Restaurant restaurant){
System.out.println(restaurant.getRestaurantName());
this.restaurantService.addRestaurant(restaurant);
return null;
}
我正在开发一个 Android 应用程序,我想用它连接到一个基于 Spring-MVC 的 Web 应用程序。目前我正在为 webapp 构建一个 restful 控制器。我尝试通过 Android 连接到控制器方法以保存我正在传递的对象。在数据库中创建了一个空行(带有 Id ofcourse)。我可以使用一些帮助来了解如何发送 Java 可以持久化的对象,以及如何检索 object/s。这是我目前所拥有的:
当前控制器:
@RequestMapping(value = "/restaurant/add",method = RequestMethod.POST)
@ResponseStatus( HttpStatus.CREATED )
@ResponseBody
public String addRestaurantWebView(Restaurant restaurant){
System.out.println("Restaurant details are"+restaurant.getRestaurantName());
return "true";
}
Spring bean :
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:ref bean="jsonMessageConverter"/>
</beans:property>
</beans:bean>
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
餐厅实体:
@Entity
@Table(name="restaurant")
public class Restaurant implements UserDetails{
private static final GrantedAuthority USER_AUTH = new SimpleGrantedAuthority("ROLE_RESTO");
private static final String emailRegexp = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$";
@Id
@Column(name="restaurantid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "restaurant_seq_gen")
@SequenceGenerator(name = "restaurant_seq_gen",sequenceName = "restaurant_seq")
private int restaurantId;
@Column(name = "restaurantname")
private String restaurantName;
@Column(name = "restaurantemail")
private String restaurantEmail;
@Column(name = "restaurantaddress")
private String restaurantAddress;
@Column(name = "password")
private String password;
@Column(name = "postleitzahl")
private int postLeitZahl;
@Column(name = "phonenumber")
private int phoneNumber;
@Column(name = "speciality")
private String restaurantSpeciality;
@Column(name = "city")
private String city;
@Transient
private List<GrantedAuthority> authorities;
@OneToMany(mappedBy = "restaurantforrating", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
private Set<Rating> ratingSet = new HashSet<>();
public Set<Rating> getRatingSet(){return this.ratingSet;}
public void setRatingSet(Set<Rating> ratingSet){
this.ratingSet = ratingSet;
}
@OneToMany(mappedBy = "restaurantmenucard", fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
private Set<MenuCard> menuCardSet = new HashSet<>();
public Set<MenuCard> getMenuCardSet(){
return this.menuCardSet;
}
public void setMenuCardSet(Set<MenuCard> menuCardSet){
this.menuCardSet = menuCardSet;
}
Android 发送对象的代码:
字符串url = "http://192.168.178.40:8080/restaurant/add";
@Override
public void addRestaurant(Restaurant restaurant) {
Log.d("Restaurant Name",restaurant.getRestaurantName());
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON);
// HttpEntity entity = new HttpEntity(restaurant,headers);
//ResponseEntity<String> out = restTemplate.exchange(url, HttpMethod.POST,entity,String.class);
String response = restTemplate.postForObject(url,restaurant,String.class);
Log.d(response,"Response from webserver is");
}
});
thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
}
Android 错误日志:
02-19 10:01:14.099 2266-2285/com.example.myapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-166
Process: com.example.myapp, PID: 2266
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:76)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:524)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:481)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:439)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:317)
at com.example.myapp.RestaurantServiceImpl.run(RestaurantServiceImpl.java:32)
at java.lang.Thread.run(Thread.java:818)
02-19 10:01:14.826 2266-2266/com.example.myapp I/Choreographer﹕ Skipped 41 frames! The application may be doing too much work on its main thread.
这就是目前的情况。现在真的很烦人,因为我不知道也无法在网上找到我做错了什么。服务器中的 Java class 是否需要与 Android 中的完全匹配,因为 Android Java class 中没有映射。
尝试向您的 spring 控制器添加 @RequestBody 注释。
@RequestMapping(value = "/restaurant/add",method = RequestMethod.POST)
@ResponseBody
public String addRestaurantWebView(@RequestBody Restaurant restaurant){
System.out.println(restaurant.getRestaurantName());
this.restaurantService.addRestaurant(restaurant);
return null;
}