Sending Objects from Spring MVC 3 REST client to REST provider

10,688

Reasons for your issues:

  1. If you want to accept data in your controller through @RequestParam, the request should contain the data as, well request parameters. Think url containing ?empCode=xyz&password=abc. Or in the request body as empCode=xyz&password=abc

  2. The way you are sending an Employee object in the client code, the object will be serialized into the request body. With the code you have provided, the client will make a request with the employee object converted to its JSON representation in the request body. Something your controller method is not equipped to read. (Assuming you have mapping jackson jars in the classpath)

Possible solutions:

  1. Change the controller method signature, instead of @RequestParam, use @RequestBody, which tell Spring to extract the value of the Employee object from the request body. It will detect that this is a json request, it will look for a JSON Http Message Converter in the context and create your employee object.

  2. Second option is to keep the controller signature, but change the way the request is made. In the client, after instantiating a RestTemplate instance, set a Form Http Message converter into its converters property. This will tell the client to POST data like a form submit. Which will be readable by your @RequestParam annotated controller method argument.

Hope this helps.

Share:
10,688
Alvin
Author by

Alvin

Updated on June 13, 2022

Comments

  • Alvin
    Alvin almost 2 years

    My intention is to create a Spring 3 MVC web client and Spring MVC REST provider as well.

    Here is the code for my REST provider:

    @RequestMapping("employee")
    public class EmployeeController {
        @Autowired 
        EmployeeDAO empDao;
    
        @RequestMapping(value = "authenticateUser", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
        public String authenticateUser(HttpServletRequest request, @RequestParam Employee employee) {
            String username = employee.getEmpCode();
            String password = employee.getPassword();
    
            String notExisting = "notExisting";
            String successLogin = "successLogin";
            String wrongPassword = "wrongPassword";
    
            Employee retrievedEmployee = empDao.getById(username);
            if(retrievedEmployee == null) {
                return notExisting;
            } else {
                if(retrievedEmployee.getPassword().equals(password)) {
                    return successLogin;
                } else {
                    return wrongPassword;
                }
            }
        }
    }
    

    and here the code for my web client:

    @Controller
    public class UserAuthenticationController {
        private final static String SERVICEURL = "http://localhost:8080/cimweb";
    
        /**
         * Simply selects the home view to render by returning its name.
         */
        @RequestMapping(value = "/userAuthentication", method = RequestMethod.POST)
        public @ResponseBody String userAuthentication(Locale locale, Model model, HttpServletRequest request) {
            Employee employee = new Employee();
            String username = request.getParameter("username");
            String password = request.getParameter("password");
    
            employee.setEmpCode(username);
            employee.setPassword(password);
    
            // Prepare acceptable media type
            List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
            acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
    
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(acceptableMediaTypes);
            HttpEntity<Employee> entity = new HttpEntity<Employee>(employee, headers);
    
            RestTemplate restTemplate = new RestTemplate();
            String url = SERVICEURL + "/employee/authenticateUser";
            try {
                ResponseEntity<Employee> result = restTemplate.exchange(url, HttpMethod.POST, entity, Employee.class);
            } catch(Exception e) {
                e.printStackTrace();
            }
    
            return "home";
        }
    }
    

    I just want to pass the object Employee to the REST provider so that I can process it and return the String from the REST provider back to the client.

    Every time I debug this, when I reach the provider I get null.

    I know I missed a lot of things and I have read a few but mostly I see are straight forward request from provider and not an object.

    Also, is there any required bean that I should place inside my servlet-context.xml?