CRUD using Spring MVC 4.0 RESTful Web Services and AngularJS
Based on the requests from many readers, I am now presenting an article on how to make CRUD operations using Spring MVC 4.0 RESTFul we...
https://www.programming-free.com/2014/07/crud-springmvc-restful-webservices-angularjs.html?m=0
Based on the requests from many readers, I am now presenting an article on how to make CRUD operations using Spring MVC 4.0 RESTFul web services and AngularJS. I had already written few articles on Spring MVC 4.0 RESTFul Web Services in case you are new to this.
For the sake of best understanding, I came up with a small task manager AngularJS application powered by Spring MVC 4.0 RESTFul Web Services. With this application, you can list all existing tasks, create a new task, mark completion of an existing task and archive completed tasks. I had tried to keep it very simple as this is not for real time use but for the best understanding of the concept.
Update:
Check out the sample application re-written using Spring Data Rest, Spring Booot and AngularJS here.
Prerequisites
-- MySql Server
-- Eclipse J2EE
-- Tomcat Server v7.0
1. Let us start by creating task table in MySql Server.
Execute the below commands in MySql Server. This will create a dedicated database for our application and will create a task_list table with dummy values to start with initially,
use taskmanager; create table task_list(task_id int not null auto_increment, task_name varchar(100) not null, task_description text,task_priority varchar(20),task_status varchar(20),task_start_time datetime not null,task_end_time datetime not null,task_archived bool default false,primary key(task_id)); insert into task_list values(1,'Gathering Requirement','Requirement Gathering','MEDIUM','ACTIVE',curtime(),curtime() + INTERVAL 3 HOUR,0); insert into task_list values(2,'Application Designing','Application Designing','MEDIUM','ACTIVE',curtime(),curtime() + INTERVAL 2 HOUR,0); insert into task_list values(3,'Implementation','Implementation','MEDIUM','ACTIVE',curtime(),curtime() + INTERVAL 3 HOUR,0); insert into task_list values(4,'Unit Testing','Unit Testing','LOW','ACTIVE',curtime(),curtime() + INTERVAL 4 HOUR,0); insert into task_list values(5,'Maintanence','Maintanence','LOW','ACTIVE',curtime(),curtime() + INTERVAL 5 HOUR,0); select * from task_list;
2. Download
-- Spring MVC 4.0 jar files from this maven repository here.
-- Download latest version of jackson json library from here
(1) jackson-annotations-x.x.x.jar
(2) jackson-core-x.x.x.jar
(3) jackson-databind-x.x.x.jar
3. Create a dynamic web project in eclipse and add the above downloaded jar files to your application WEN-INF\lib folder.
I have already explained component-scan element and mvc:annotation-driven element in my previous article, so I am not going to repeat it here again.
Keep yourself subscribed for getting programmingfree articles delivered directly to your inbox once in a month. Thanks for reading!
4. Now edit web.xml file under WebContent folder to notify the application container about the spring configuration file. Add below code before </web-app>
5. Create a file under WEB-INF folder and name it as "rest-servlet.xml". Add below spring configuration code to it,
<servlet> <servlet-name>rest</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
Note that in the above code,we have named Spring Dispatcher servlet class as "rest" and the url pattern is given as "/*" which means any uri with the root of this web application will call DispatcherServlet. So what's next? DispatcherServlet will look for configuration files following this naming convention - [servlet-name]-servlet.xml. In this example, I have named dispatcher servlet class as "rest" and hence it will look for file named 'rest-servlet.xml'.
5. Create a file under WEB-INF folder and name it as "rest-servlet.xml". Add below spring configuration code to it,
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <context:component-scan base-package="com.programmingfree.springservice.controller" /> <mvc:annotation-driven /> </beans>
I have already explained component-scan element and mvc:annotation-driven element in my previous article, so I am not going to repeat it here again.
6. Create a Java class and name it "Task.java". This is the model class and it represents the fields of a single task in the database.
package com.programmingfree.springservice.domain; public class Task { private int task_id; private String task_name; private String task_description; private String task_priority; private String task_status; public int getTaskId() { return task_id; } public void setTaskId(int taskId) { this.task_id = taskId; } public String getTaskName() { return task_name; } public void setTaskName(String taskName) { this.task_name = taskName; } public String getTaskDescription() { return task_description; } public void setTaskDescription(String taskDescription) { this.task_description = taskDescription; } public String getTaskPriority() { return task_priority; } public void setTaskPriority(String taskPriority) { this.task_priority = taskPriority; } public String getTaskStatus() { return task_status; } public void setTaskStatus(String taskStatus) { this.task_status = taskStatus; } @Override public String toString() { return "Task [task_id=" + task_id + ", task_name=" + task_name + ", task_description=" + task_description + ", task_priority=" + task_priority +",task_status="+task_status+ "]"; } }
7. Create a utility class to handle connections to database. The connection string properties are kept in a configuration file called "config.properties" in the src folder.
package com.programmingfree.springservice.utility; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public class DBUtility { private static Connection connection = null; public static Connection getConnection() { if (connection != null) return connection; else { try { Properties prop = new Properties(); InputStream inputStream = DBUtility.class.getClassLoader().getResourceAsStream("/config.properties"); prop.load(inputStream); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); Class.forName(driver); connection = DriverManager.getConnection(url, user, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return connection; } } }
Properties configuration file should have contents such as this,
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/databasename
user=username
password=xxxxxx
8. Create a service class that performs data access operations to get data from database,
9. Create Spring Controller class that maps the incoming request to appropriate methods and returns response in json format. We are going to use @RestController annotation which has @Controller and @Responsebody annotated within itself.
Let us now take a closer look into the methods we have in the Spring Controller class.
-- Initially we use getAllTasks () method to fetch all tasks from database. This will fetch all tasks that are not archived (task_archived = '0').
-- Then we give an option to the user via archiveTasks() method, to archive all completed tasks so that it won't show up on the dashboard. For this purpose, we have a field in task_list table called 'task_archived' with values 0 or 1 marking whether a task is archived or not.
-- An option to update the status of a task from 'ACTIVE' to 'COMPLETED' or vice-versa is provided in the changeStatus() method
-- AddTask() method enables one to add a new task to the database.
10. Let us now create the jsp file that sends requests to the Spring controller to fetch data and to update data in the server,
Note that I have not included any styling elements or animations though I have used it in the demonstration to keep the code clean for easy understanding.
11. In the above JSP file, I had referenced a javascript file called 'app.js' in the head section. Create a file called 'app.js' under WebContent/js folder and copy the below code in it.
-- AngularJS gets activated with the ng-app directive placed in the html tag.
-- When the browser loads the div element with ng-controller directive 'taskManagerController', the controller module in the above javascript file executes. It makes http call to get all tasks initially and display in the jsp file.
-- When the user checks the check box placed near every task, the task is marked completed and when the user unchecks the check box, the task is again marked active.
-- On clicking 'Clear Completed Tasks' button, archiveTasks() method in the above javascript file is executed and all the tasks that are marked as completed are archived by changing the value of task_archived field in the database to 1. This method makes an http post request to the server to change the task_archived field value of all completed tasks. Note that we are just archiving the tasks but not deleting it, so it will always be there in the database but won't show up in the application.
-- A new task entry is added to the database by making an http post when the user clicks on 'Add task' button.
To understand how this application works, you can see a simple static demonstration using the demo link below. To completely understand how this works from the server side with a database, download the application and run it yourself using the instructions below.
package com.programmingfree.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.programmingfree.springservice.domain.*; import com.programmingfree.springservice.utility.DBUtility; public class TaskManagerService { private Connection connection; public TaskManagerService() { connection = DBUtility.getConnection(); } public void addTask(Task task) { try { PreparedStatement preparedStatement = connection .prepareStatement("insert into task_list(task_name,task_description,task_priority,task_status,task_archived,task_start_time,task_end_time) values (?, ?, ?,?,?,?,?)"); System.out.println("Task:"+task.getTaskName()); preparedStatement.setString(1, task.getTaskName()); preparedStatement.setString(2, task.getTaskDescription()); preparedStatement.setString(3, task.getTaskPriority()); preparedStatement.setString(4, task.getTaskStatus()); preparedStatement.setInt(5,0); Date dt = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String currentTime = sdf.format(dt); preparedStatement.setString(6,currentTime); preparedStatement.setString(7,currentTime); preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void archiveTask(int taskId) { try { PreparedStatement preparedStatement = connection .prepareStatement("update task_list set task_archived=true where task_id=?"); // Parameters start with 1 preparedStatement.setInt(1, taskId); preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void updateTask(Task task) throws ParseException { try { PreparedStatement preparedStatement = connection .prepareStatement("update task_list set task_name=?, task_description=?, task_priority=?,task_status=?" + "where task_id=?"); preparedStatement.setString(1, task.getTaskName()); preparedStatement.setString(2, task.getTaskDescription()); preparedStatement.setString(3, task.getTaskPriority()); preparedStatement.setString(4, task.getTaskStatus()); preparedStatement.setInt(4, task.getTaskId()); preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public void changeTaskStatus(int taskId,String status) throws ParseException { try { PreparedStatement preparedStatement = connection .prepareStatement("update task_list set task_status=? where task_id=?"); preparedStatement.setString(1,status); preparedStatement.setInt(2, taskId); preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } } public List<Task> getAllTasks() { List<Task> tasks = new ArrayList<Task>(); try { Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery("select * from task_list where task_archived=0"); while (rs.next()) { Task task = new Task(); task.setTaskId(rs.getInt("task_id")); task.setTaskName(rs.getString("task_name")); task.setTaskDescription(rs.getString("task_description")); task.setTaskPriority(rs.getString("task_priority")); task.setTaskStatus(rs.getString("task_status")); tasks.add(task); } } catch (SQLException e) { e.printStackTrace(); } return tasks; } public Task getTaskById(int taskId) { Task task = new Task(); try { PreparedStatement preparedStatement = connection. prepareStatement("select * from task_list where task_id=?"); preparedStatement.setInt(1, taskId); ResultSet rs = preparedStatement.executeQuery(); if (rs.next()) { task.setTaskId(rs.getInt("task_id")); task.setTaskName(rs.getString("task_name")); task.setTaskDescription(rs.getString("task_description")); task.setTaskPriority(rs.getString("task_priority")); task.setTaskStatus(rs.getString("task_status")); } } catch (SQLException e) { e.printStackTrace(); } return task; } }
9. Create Spring Controller class that maps the incoming request to appropriate methods and returns response in json format. We are going to use @RestController annotation which has @Controller and @Responsebody annotated within itself.
package com.programmingfree.springservice.controller; import java.text.ParseException; import java.util.List; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.programmingfree.dao.TaskManagerService; import com.programmingfree.springservice.domain.Task; @RestController public class TaskManagerController { TaskManagerService taskmanagerservice=new TaskManagerService(); @RequestMapping(value="/tasks",method = RequestMethod.GET,headers="Accept=application/json") public List<Task> getAllTasks() { List<Task> tasks=taskmanagerservice.getAllTasks(); return tasks; } @RequestMapping(value="/tasks/archive/{taskIds}",method = RequestMethod.POST,headers="Accept=application/json") public List<Task> archiveAllTasks(@PathVariable int[] taskIds) { for(int i=0;i<taskIds.length;i++){ taskmanagerservice.archiveTask(taskIds[i]); } List<Task> tasks=taskmanagerservice.getAllTasks(); return tasks; } @RequestMapping(value="/tasks/{taskId}/{taskStatus}",method = RequestMethod.POST,headers="Accept=application/json") public List<Task> changeTaskStatus(@PathVariable int taskId,@PathVariable String taskStatus) throws ParseException { taskmanagerservice.changeTaskStatus(taskId,taskStatus); return taskmanagerservice.getAllTasks(); } @RequestMapping(value="/tasks/insert/{taskName}/{taskDesc}/{taskPriority}/{taskStatus}",method = RequestMethod.POST,headers="Accept=application/json") public List<Task> addTask(@PathVariable String taskName,@PathVariable String taskDesc,@PathVariable String taskPriority,@PathVariable String taskStatus) throws ParseException { Task task = new Task(); task.setTaskName(taskName); task.setTaskDescription(taskDesc); task.setTaskPriority(taskPriority); task.setTaskStatus(taskStatus); taskmanagerservice.addTask(task); return taskmanagerservice.getAllTasks(); } }
Let us now take a closer look into the methods we have in the Spring Controller class.
-- Initially we use getAllTasks () method to fetch all tasks from database. This will fetch all tasks that are not archived (task_archived = '0').
-- Then we give an option to the user via archiveTasks() method, to archive all completed tasks so that it won't show up on the dashboard. For this purpose, we have a field in task_list table called 'task_archived' with values 0 or 1 marking whether a task is archived or not.
-- An option to update the status of a task from 'ACTIVE' to 'COMPLETED' or vice-versa is provided in the changeStatus() method
-- AddTask() method enables one to add a new task to the database.
10. Let us now create the jsp file that sends requests to the Spring controller to fetch data and to update data in the server,
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html ng-app="taskManagerApp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>AngularJS Task Manager</title> <script data-require="angular.js@*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script> <script type="text/javascript" src="./js/app.js"></script> </head> <body> <div ng-controller="taskManagerController"> <div id="task-panel" class="fadein fadeout showpanel panel" ng-show="toggle"> <div class="panel-heading"> <i class="panel-title-icon fa fa-tasks"></i> <span class="panel-title">Recent Tasks</span> <div class="panel-heading-controls"> <button ng-click="toggle = !toggle" >Add New Task</button> <button confirmed-click="archiveTasks()" ng-confirm-click="Would you like to archive completed tasks?">Clear completed tasks</button> </div> </div> <div> <div ng-repeat="task in tasks"> <span> {{task.taskPriority}} </span> <div> <input id="{{task.taskId}}" type="checkbox" value="{{task.taskId}}" ng-checked="selection.indexOf(task.taskId) > -1" ng-click="toggleSelection(task.taskId)" /> <label for="{{task.taskId}}"></label> </div> <div ng-if="task.taskStatus=='COMPLETED'"> <a href="#" class="checkedClass"> {{task.taskName}} <span class="action-status">{{task.taskStatus}}</span> </a> </div> <div ng-if="task.taskStatus=='ACTIVE'"> <a href="#" class="uncheckedClass"> {{task.taskName}} <span class="action-status">{{task.taskStatus}}</span> </a> </div> </div> </div> </div> <div id="add-task-panel" ng-hide="toggle"> <div> <span>Add Task</span> <div> <button ng-click="toggle = !toggle">Show All Tasks</button> </div> </div> <div> <div> <table> <tr> <td>Task Name:</td> <td><input type="text" ng-model="taskName"/></td> </tr> <tr> <td>Task Description:</td> <td><input type="text" ng-model="taskDesc"/></td> </tr> <tr> <td>Task Status:</td> <td> <select ng-model="taskStatus" ng-options="status as status for status in statuses"> <option value="">-- Select --</option> </select> </td> </tr> <tr> <td>Task Priority:</td> <td> <select ng-model="taskPriority" ng-options="priority as priority for priority in priorities"> <option value="">-- Select --</option> </select> </td> </tr> <tr> <td><br/><button ng-click="addTask()" class="btn-panel-big">Add New Task</button></td> </tr> </table> </div> </div> </div> </div> </body> </html>
Note that I have not included any styling elements or animations though I have used it in the demonstration to keep the code clean for easy understanding.
11. In the above JSP file, I had referenced a javascript file called 'app.js' in the head section. Create a file called 'app.js' under WebContent/js folder and copy the below code in it.
var taskManagerModule = angular.module('taskManagerApp', ['ngAnimate']); taskManagerModule.controller('taskManagerController', function ($scope,$http) { var urlBase="http://localhost:8080/TaskManagerApp"; $scope.toggle=true; $scope.selection = []; $scope.statuses=['ACTIVE','COMPLETED']; $scope.priorities=['HIGH','LOW','MEDIUM']; $http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; //get all tasks and display initially $http.get(urlBase+'/tasks'). success(function(data) { $scope.tasks = data; for(var i=0;i<$scope.tasks.length;i++){ if($scope.tasks[i].taskStatus=='COMPLETED'){ $scope.selection.push($scope.tasks[i].taskId); } } }); //add a new task $scope.addTask = function addTask() { if($scope.taskName=="" || $scope.taskDesc=="" || $scope.taskPriority == "" || $scope.taskStatus == ""){ alert("Insufficient Data! Please provide values for task name, description, priortiy and status"); } else{ $http.post(urlBase + '/tasks/insert/' +$scope.taskName+'/'+$scope.taskDesc+'/'+$scope.taskPriority+'/'+$scope.taskStatus). success(function(data) { alert("Task added"); $scope.tasks = data; $scope.taskName=""; $scope.taskDesc=""; $scope.taskPriority=""; $scope.taskStatus=""; $scope.toggle='!toggle'; }); } }; // toggle selection for a given task by task id $scope.toggleSelection = function toggleSelection(taskId) { var idx = $scope.selection.indexOf(taskId); // is currently selected if (idx > -1) { $http.post(urlBase + '/tasks/' +taskId+'/ACTIVE'). success(function(data) { alert("Task unmarked"); $scope.tasks = data; }); $scope.selection.splice(idx, 1); } // is newly selected else { $http.post(urlBase + '/tasks/' +taskId+'/COMPLETED'). success(function(data) { alert("Task marked completed"); $scope.tasks = data; }); $scope.selection.push(taskId); } }; // Archive Completed Tasks $scope.archiveTasks = function archiveTasks() { $http.post(urlBase + '/tasks/archive/' + $scope.selection). success(function(data) { $scope.tasks = data; alert("Successfully Archived"); }); }; }); //Angularjs Directive for confirm dialog box taskManagerModule.directive('ngConfirmClick', [ function(){ return { link: function (scope, element, attr) { var msg = attr.ngConfirmClick || "Are you sure?"; var clickAction = attr.confirmedClick; element.bind('click',function (event) { if ( window.confirm(msg) ) { scope.$eval(clickAction); } }); } }; }]);
-- AngularJS gets activated with the ng-app directive placed in the html tag.
-- When the browser loads the div element with ng-controller directive 'taskManagerController', the controller module in the above javascript file executes. It makes http call to get all tasks initially and display in the jsp file.
-- When the user checks the check box placed near every task, the task is marked completed and when the user unchecks the check box, the task is again marked active.
-- On clicking 'Clear Completed Tasks' button, archiveTasks() method in the above javascript file is executed and all the tasks that are marked as completed are archived by changing the value of task_archived field in the database to 1. This method makes an http post request to the server to change the task_archived field value of all completed tasks. Note that we are just archiving the tasks but not deleting it, so it will always be there in the database but won't show up in the application.
-- A new task entry is added to the database by making an http post when the user clicks on 'Add task' button.
To understand how this application works, you can see a simple static demonstration using the demo link below. To completely understand how this works from the server side with a database, download the application and run it yourself using the instructions below.
Instructions to run the download
1. Download the project using the download link above and unzip it.
2. Follow Step 1 of this article to create a database, table with dummy values. Simply execute the given query.
3. Make sure MySql Service is running.
4. Import the downloaded project in eclipse.
5. Right Click 'index.jsp' and run it in Tomcat Web Server v7.0
6. Note that you need data connection to get angularjs up and running in the project as we have referenced the latest version from angularjs cdn repository directly. You can also download angularjs library and reference it in index.jsp
You must be seeing the following page once you run it from Tomcat Web Server,
Keep yourself subscribed for getting programmingfree articles delivered directly to your inbox once in a month. Thanks for reading!
Hi Greg,
ReplyDeleteThank you so much for doing this. I am looking in to it and my next article is going to use the same application but with MySql Database and Spring Data Rest. I will keep you posted on this.
Thanks,
Priya
Hi Priya
ReplyDeleteGood article and thanks
Regards
Sentil
Nice post.......
ReplyDeleteRegards,
VV Nagesh.
Hi Im new to REST , I was doing happily doing these tutorials until this one ;) I am struggling with archiveAllTasks() method, looks like there are mistakes in it, could you clarify this? Also whenever you use List should it not be List as you declared the class as Task not task .
ReplyDeleteMany thanks for the tutorials
Hi Priya,
ReplyDeleteMy comment hopefully hasn't posted twice as seems to have lost it. Thanks for great article as was looking for something with Spring and Angular today and this was perfect series of articles. Just a small few things in the article versus your GitHub downloadable code which is perfect. I was initially following along using copy/paste function in my own project. Lines 28-44 of your TaskManagerController class do not render correctly in the article so if a user copies to an IDE they'll get compile errors. I had to clean it up against your GitHub download code. Also in the article, the Task class is sometimes referred to in the code blocks using lower-case "t" so again the IDE will throw an unrecognized type error as it should be Task - your GitHub code though is perfect so it won't show up there. And last minor thing was the article uses "db.properties" in the text content, but code and GitHub demo code refer to "config.properties" so won't affect anybody using your downloadable demo, just somebody if they like me just follow article and build own project so article text should use "config.properties" to be in sync with your DBUtility java source code otherwise Tomcat will throw an error. Anyway, great and nicely explained demo and project. Just to note I ran this on Apache Tomcat 8.0.24 on Mac OSX Yosemite without any issues after the tweaks.Thanks again for posting such a good series.
Hi Niall,
DeleteFirst of all, thank you very much for a wonderful comment and for pointing out the mistakes for the benefit of other readers. I have made the changes you mentioned in your comment. Let me know if there is still anything that needs an update. Thanks Again :)
Excellent example PriyaDarshini. Explains well about things in simple manner
ReplyDeleteHi,
ReplyDeleteIn app.js in $scope.tasks[i].taskId ,where you are getting taskId because in pojo class(task.java) you defined task_id not taskId.
Hi,
ReplyDeleteIn app.js in $scope.tasks[i].taskId ,where you are getting taskId because in pojo class(task.java) you defined task_id not taskId.
if anyone knows the answer please reply,need urgent help.
Okay. This is how it works. Spring uses Jackson Json Library to convert java objects to json values. Jackson Library tries to match the values with the field names based on getters and setters. This is what I know for now. Hope this helps!
Deletehttp://stackoverflow.com/questions/22162916/how-does-the-jackson-mapper-know-what-field-in-each-json-object-to-assign-to-a-c
hello
ReplyDeleteWhy the UrlBase is var urlBase="http://localhost:8080/TaskManagerApp";
instead of
var urlBase="http://localhost:8080";
from where does TaskManagerApp come into picture
hi
ReplyDeletefrom the spring controller, your are returning a list..i wanted to know how does it maps back to the page.
Because when i am doing the same, it returns to error function in app.js
While downloading taskmanager service file is not available in zip.Help please
ReplyDeleteNice post. Thanks for sharing! I want people to know just how good this information is in your article. It’s interesting content and Great work.
ReplyDeleteThanks & Regards,
VRIT Professionals,
No.1 Leading Web Designing Training Institute In Chennai.
Looking for help with marketing mix assignment? Get it done with Marketing Mix Assignment Help. It will complete your assignment within the due date at affordable prices.
ReplyDeletesomething that is remarkable and should be learned. Thank you for providing this great information
ReplyDelete토토
바카라사이트
파워볼
카지노사이트
It's exactly what I'm looking for. I really appreciate your efforts in writing this kind of content for us.
ReplyDelete스포츠토토
토토
안전놀이터
토토사이트
It is truly a nice and useful piece of info. I am glad that you just shared this useful information with us. Please stay us up to date like this. Thanks for sharing.
ReplyDelete토토사이트
온라인카지노
파워볼게임
바카라사이트