0

I am working on an Android application with which I want to connect to a Spring-MVC based webapp. Currently I am working on building a restful controller for the webapp. I tried connecting via Android to the controller method to save an object which I am passing. A null row (with Id ofcourse) in database was created. I can use some help in knowing how can I send Java objects which can be persisted, and retrieval of object/s. Here is what I have so far :

Current controller :

    @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"/>

Restaurant Entity :

@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 code to send object :

String 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 error log :

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$1.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.

THis is the current situation guys. It is really getting annoying now as I don't know and cannot find on net what I am doing wrong. Does the Java class in server need to completely match the one on Android, as there are no mappings in Android Java class.

We are Borg
  • 5,117
  • 17
  • 102
  • 225
  • You need to decide what data format you want to use to exchange data (JSON, XML ...) and then from Spring you can use http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/ if you choose json or http://www.mkyong.com/spring-mvc/spring-3-mvc-and-xml-example/ if you choose xml – ccheneson Feb 18 '15 at 15:45
  • @ccheneson : Thanks, after research I found that, I am already writing code with JSON. I am editing my post now, please give me 2 minutes. Can you please tell me why I am getting null entries in database. THanks. – We are Borg Feb 18 '15 at 15:47
  • You will have to debug it. If you manage to insert a `restaurant` object (with null attributes) in db, the problem may be from when you send the request to your controller, or the mapping with @ModelAttribute (I dont know that much of Spring MVC) – ccheneson Feb 18 '15 at 15:58
  • 1
    try adding @RequestBody to addRestaurantWebView(@RequestBody Restaurant restaurant) Spring Controller method – Ramesh Kotha Feb 18 '15 at 16:10
  • BTW, when you do your post, on the server side, should it be `public @ResponseBody String addRestaurantWebView(@RequestBody Restaurant restaurant){` instead of `public String addRestaurantWebView(Restaurant restaurant){`? – ccheneson Feb 18 '15 at 16:11
  • that should solve the issue @ccheneson – Ramesh Kotha Feb 18 '15 at 16:12
  • I think so too. You beat me on this ! – ccheneson Feb 18 '15 at 16:13

1 Answers1

1

Try adding @RequestBody annotation to your spring controller.

@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;
    }
Ramesh Kotha
  • 8,266
  • 17
  • 66
  • 90
  • Thank you for your answer, It is crashing my app now, and not even creating a null entity. I am posting the error log in the main post, kindly have a look. – We are Borg Feb 18 '15 at 16:37
  • put a debug point at controller method and check whether all data is coming or not. – Ramesh Kotha Feb 19 '15 at 03:10
  • Hey man, Can you please check the code I have posted now, its updated, and when I put @RequestBody, it does not even touch the server. Thanks a lot. – We are Borg Feb 19 '15 at 09:12
  • is it saving in db properly, if so spring so intelligent enough to handle itself, as the variable names are same in android and spring project – Ramesh Kotha Feb 19 '15 at 15:15
  • You were spot-on with your RequestBody, some other mistake I had made in Android code. I finished the task. Thanks a lot. – We are Borg Feb 19 '15 at 15:17