I am trying to integrate AngularJS with Spring MVC; but I am not able to post parameters to spring controller as RequestBody. Can some one help me to achieve the same. Below is brief flow of my program.
After doing data entry TodoNewController gets executed. From here I am calling user-defined method "create" which I have defined in services.js. As per the flow after this it should call create method of TodoController.java along with input params; but it is not happening. Can some one let me know what is wrong with the code. Below is the code for same.
controller.js
function TodoNewController($scope, $location, Todo) {
$scope.submit = function () {
Todo.create($scope.todo, function (todo) {
$location.path('/');
});
};
$scope.gotoTodoListPage = function () {
$location.path("/")
};
}
services.js
angular.module('todoService', ['ngResource']).
factory('Todo', function ($resource) {
return $resource('rest/todo/:id', {}, {
'create': {method:'PUT'}
});
});
TodoController.java
@Controller
public class TodoController {
private static final AtomicLong todoIdGenerator = new AtomicLong(0);
private static final ConcurrentSkipListMap<Long, Todo> todoRepository = new ConcurrentSkipListMap<Long, Todo>();
@RequestMapping(value = "/todo", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void create(@RequestBody Todo todo) {
long id = todoIdGenerator.incrementAndGet();
todo.setId(id);
todoRepository.put(id, todo);
}
}
Spring expects application/x-www-form-urlencoded as the Content-Type of the request. You may try inject $http into your service and invoke $http.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded"; at the beginning of it.
Modify the request mapping to match the actual mapping /rest/todo and change the databinding to use @ModelAttribute.
@RequestMapping(value = "/rest/todo", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void create(@ModelAttribute Todo todo) {
long id = todoIdGenerator.incrementAndGet();
todo.setId(id);
todoRepository.put(id, todo);
}
Isolate the problem first. Is it Spring or Angular that's causing the issue? I suggest you install a Rest client plugin either in Chrome or FireFox. Then create a PUT request and enter the correct endpoint URL. If you're able to receive the correct response, then it means your Angular request is constructed incorrectly.
Now, run your Angular-based client. Make a PUT request. Inspect the parameters and request sent (in Chrome, you can use Developer tools) and see if it matches the request you sent earlier. If it does, then it should work. If not, then you know the problem.
Also, your Angular resource:
$resource('rest/todo/:id')
has a different URL than what you have in your Spring controller
@RequestMapping(value = "/todo", method = RequestMethod.PUT)
So the first one is like 'rest/todo/1' and the latter is '/todo'. I don't think those would match.