Restful code example using Spring MVC
In my previous blog, I talked about Restful webservices design. In this blog, I will provide sample code for the same using Spring MVC framework.
Spring MVC 3.x supports annotation based controllers, which are Restful in nature.
Let us create a sample Spring web application for performing CRUD on User entity.
Spring MVC 3.x supports annotation based controllers, which are Restful in nature.
Let us create a sample Spring web application for performing CRUD on User entity.
Creating project:
Create a Maven project with a archetype 'maven-archetype-webapp'.
pom.xml
<!-- version property --> <properties> <spring.version>3.1.2.RELEASE</spring.version> </properties> <!-- servlet dependency for compilation --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <type>jar</type> <scope>compile</scope> </dependency> <!-- Spring MVC dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- Jackson dependency for JSON mapping--> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency>
web.xml
<servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
The servlet-name is 'mvc-dispatcher'. So we need a context xml with the name mvc-dispatcher-servlet.xml
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <context:component-scan base-package="com.myorg" /> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="stringHttpMessageConverter"/> </util:list> </property> </bean> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="mediaTypes"> <map> <entry key="html" value="text/html"/> <entry key="json" value="application/json"/> </map> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </list> </property> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> </list> </property> </bean> </beans>
Things to know:
- The namespaces in the beans element are very important as the spring container validates this xml against the xsd.
- Every xmlns attribute should have a corresponding entry in the xsi:schemaLocation attribute. Here we have used mvc, context, util prefixes.
- 'component-scan' element tells the spring container to look for com.myorg package for annotated controllers.
- 'mvc:annotation-driven' tells the spring container that we are using annotated controllers.
- InternalResourceViewResolver is used to indicate that the views are present in '/WEB-INF/view/' folder with jsp extension.
- The ContentNegotiatingViewResolver is used to produce the correct format of response from our controllers. For Restful webservices, we will need response formats like JSON,html,xml etc.
- MappingJacksonJsonView is used to convert Java POJO to JSON format.
User POJO:
public class User implements Serializable{ private static final long serialVersionUID = 10008L; private String firstName; private String lastName; private long userId; public User(String _first, String _last){ this.firstName = _first; this.lastName = _last; } public User(){ } //Setters and Getters }
User Service:
The service is a trivial implementation for brevity.public interface UserService { public User createUser(User user) throws UserCreateException; public User getUser(String userId) throws UserNotFoundException; public void updateUser(User user) throws UserNotFoundException; public void deleteUser(String userId) throws UserNotFoundException; }
Implementation is provided below. Note the @service annotation which is then injected into the controller using autowiring.
@Service public class UserServiceImpl implements UserService{ public User createUser(User user) throws UserCreateException{ //implement here user.setUserId(111); return user; } public User getUser(String userId) throws UserNotFoundException{ User user = new User(); if(userId == null){ throw new UserNotFoundException("Invalid User Id"); } user.setFirstName("John"); user.setLastName("Howard"); return user; } public void updateUser(User user) throws UserNotFoundException{ //implement here } public void deleteUser(String userId) throws UserNotFoundException{ //implement here } }
Exception classes
public class ServiceException extends Exception{ private static final long serialVersionUID = 1L; public ServiceException(String _msg){ super(_msg); } } public class AuthenticationException extends ServiceException{ private static final long serialVersionUID = 1L; public AuthenticationException(String _msg){ super(_msg); } } public class UserCreateException extends ServiceException{ private static final long serialVersionUID = 1L; public UserCreateException(String _msg){ super(_msg); } } public class UserNotFoundException extends ServiceException{ private static final long serialVersionUID = 1L; public UserNotFoundException(String _msg){ super(_msg); } }
UserController:
@Controller public class UserController extends AbstractController{ @Autowired private UserService userService; @RequestMapping(value="/restexample/users/user",method=RequestMethod.POST, produces="application/json") @ResponseBody public User createUser(@RequestBody String body, HttpServletRequest _request) throws UserCreateException,AuthenticationException{ authenticate(_request, "createUser"); String firstName = _request.getParameter("firstName"); String lastName = _request.getParameter("lastName"); User user = new User(firstName,lastName); user = userService.createUser(user); return user; } /*Invoked depending on accept header*/ @RequestMapping(value="/restexample/users/user/{userId}",method=RequestMethod.GET, produces="application/json") @ResponseBody public User getUser(@PathVariable String userId,HttpServletRequest _request) throws UserNotFoundException,AuthenticationException{ authenticate(_request, "getUser"); return userService.getUser(userId); } @RequestMapping(value="/restexample/users/user/{userId}",method=RequestMethod.GET) @ResponseBody public String getUserAsHTML(@PathVariable String userId,HttpServletRequest _request) throws UserNotFoundException,AuthenticationException{ authenticate(_request, "getUser"); User user = userService.getUser(userId); StringBuilder builder = new StringBuilder(); builder.append("FirstName: ").append(user.getFirstName()); builder.append("LastName: ").append(user.getLastName()); return builder.toString(); } @RequestMapping(value="/restexample/users/user/{userId}",method=RequestMethod.PUT) @ResponseBody public String updateUser(@PathVariable String userId,@RequestBody String body, HttpServletRequest _request) throws UserNotFoundException,AuthenticationException{ authenticate(_request, "updateUser"); long userIdVal = convertStringToLong(userId); if(userIdVal < 1){ throw new UserNotFoundException("Not a valid User Id: "+userId); } String firstName = _request.getParameter("firstName"); String lastName = _request.getParameter("lastName"); User user = new User(firstName,lastName); user.setUserId(userIdVal); userService.updateUser(user); return "success"; } @RequestMapping(value="/restexample/users/user/{userId}",method=RequestMethod.DELETE) @ResponseBody public String deleteUser(@PathVariable String userId,@RequestBody String body, HttpServletRequest _request) throws UserNotFoundException,AuthenticationException{ authenticate(_request, "createUser"); User user = new User(); userService.deleteUser(userId); return "success"; } public void authenticate(HttpServletRequest _request, String _serviceName) throws AuthenticationException{ String hashKey = _request.getHeader("hashKey"); boolean valid = true; //validate hashkey if(!valid){ throw new AuthenticationException(_serviceName); } } }
AbstractController:
public abstract class AbstractController { private final String USER_NOT_FOUND_ERROR_CODE = "1002"; private final String USER_NOT_FOUND_ERROR_DESC = "The provided user cannot be found."; private final String AUTHENTICATION_ERROR_CODE = "1003"; private final String AUTHENTICATION_ERROR_DESC = "You are not authorized to access this service."; private final String USER_CREATION_ERROR_CODE = "1001"; private final String USER_CREATION_ERROR_DESC = "User creation failed. "; private final String UKNOWN_ERROR_CODE = "1000"; private final String UKNOWN_ERROR_DESC = "An unknown error has occurred"; @ExceptionHandler(ServiceException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public RestError handleServiceException(ServiceException ex, HttpServletResponse _request){ RestError error = new RestError(); if(ex instanceof AuthenticationException){ error.setErrorCode(AUTHENTICATION_ERROR_CODE); error.setErrrorDesc(AUTHENTICATION_ERROR_DESC); } else if(ex instanceof UserCreateException){ error.setErrorCode(USER_CREATION_ERROR_CODE); error.setErrrorDesc(USER_CREATION_ERROR_DESC); } else if(ex instanceof UserNotFoundException){ error.setErrorCode(USER_NOT_FOUND_ERROR_CODE); error.setErrrorDesc(USER_NOT_FOUND_ERROR_DESC); } else { error.setErrorCode(UKNOWN_ERROR_CODE); error.setErrrorDesc(UKNOWN_ERROR_DESC); } return error; } }
RestError:
public class RestError implements Serializable{ private static final long serialVersionUID = 198L; private String errorCode; private String errrorDesc; //Setters and getters }
Things to know:
- The controller extends from AbstractController which is explained later.
- @RequestMapping can be used to map the Rest URI to the method. We can add parameters to the URI like {userId}
- The parameters are mapped to variables through PathVariable
- The method can declare what media type it is consuming/producing. For eg, produces="application/json"
- The method can also declare what request type it is accepting through method=RequestMethod.POST/PUT/GET etc.
- The accept header set by the client will be used to determine the method to be invoked.
- The method can declare that it is returning a response in the Response body through @ResponseBody.
- If the response type is a custom object like 'User', Jakson Mapping view will convert it to JSON format if required.
- The authentication performed here is simple authentication by using a secret hash key (which is preagreed by client/server).This hash key is sent across in the request header.
- The same URI can be mapped to send across different response formats.
- The getUserAsHTML() and getUser() map to same URI. However, getUserAsHTML() returns html content (the method can return a div content) whereas getUser() returns JSON content.
Handling exceptions:
The @ExceptionHandler annotation could be used to handle the exceptions. However, Spring requires every controller to have its own @ExceptionHandler annotated method.
To overcome this, we can have an abstract controller and have the exception handling at a common place. We can have different methods for each type of exception, or as in the example, we can handle the super exception class which is ServiceException and then handle individually.
If you are using Spring 3.2, you can use the @controlleradvice annotation and use any class for exception handling.
If you are using Spring 3.2, you can use the @controlleradvice annotation and use any class for exception handling.
Rest Services generally should provide meaningful error messages and custom error codes when there is an error. At the same time, it should also prevent the internal exception hierarchy from reaching the client. In our example, the RestError object will which is returned by the exception handler will be converted to JSON format and returned back to the client.
Note that the error messages could be enumerated for better clarity.
Testing:
I have used Soap Client for testing. We can set the request type POST/GET etc and aslo the accept headers (application/json etc)
Following is the sample responses for a few requests:
Error Response:
HTTP response: HTTP/1.1 400 Bad Request Server: Apache-Coyote/1.1 Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Tue, 20 Aug 2013 11:26:01 GMT Connection: close {"errorCode":"1003","errrorDesc":"You are not authorized to access this service. "} JSON: { "errorCode": "1003", "errrorDesc": "You are not authorized to access this service. " }
Success response as JSON:
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: application/json Transfer-Encoding: chunked Date: Tue, 20 Aug 2013 11:58:09 GMT {"firstName":"John","lastName":"Howard","userId":111}
thanks for ur post
ReplyDeleteplease tell me url for test via SOAP UI
thanks again :-)
Hi Thanks for visit us:
ReplyDeleteARKA Softwares & Outsourcing is an IT Company focusing on software & Web development and providing offshore outsourcing solutions to enterprises worldwide.website designing company in usa
Great list and thanks for sharing this article…
ReplyDeleteMobile App Development Company Indore
wow really nice and the explanations are very clear manner
ReplyDeletejava j2ee training course contents | java j2ee training institutes in chennai | java j2ee training | java training in chennai velachery
Thanks for sharing this article
ReplyDeleteJava Training in Chennai
I really enjoy simply reading all of your weblogs. Simply wanted to inform you that you have people like me who appreciate your work. Definitely a great post I would like to read this
ReplyDeleteangularjs online Training
angularjs Training in marathahalli
angularjs interview questions and answers
angularjs Training in bangalore
angularjs Training in bangalore
angularjs online Training
I recently came across your blog and have been reading along. I thought I would leave my first comment.
ReplyDeleteJava training in Bangalore | Java training in Kalyan nagar
Java training in Bangalore | Java training in Kalyan nagar
Java training in Bangalore | Java training in Jaya nagar
This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.
ReplyDeleterpa training in chennai
rpa training in bangalore
rpa course in bangalore
best rpa training in bangalore
rpa online training
I think you have a long story to share and i am glad after long time finally you cam and shared your experience.
ReplyDeletepython course institute in bangalore
python Course in bangalore
python training institute in bangalore
I have been meaning to write something like this on my website and you have given me an idea. Cheers.
ReplyDeleteData Science Training in Indira nagar
Data Science Training in btm layout
Python Training in Kalyan nagar
Data Science training in Indira nagar
Data Science Training in Marathahalli | Data Science training in Bangalore
Greetings. I know this is somewhat off-topic, but I was wondering if you knew where I could get a captcha plugin for my comment form? I’m using the same blog platform like yours, and I’m having difficulty finding one? Thanks a lot.
ReplyDeleteAdvanced AWS Online Training | Advanced Online AWS Certification Course - Gangboard
Best AWS Training in Chennai | Amazon Web Services Training Institute in Chennai Velachery, Tambaram, OMR
Advanced AWS Training in Bangalore |Best AWS Training Institute in Bangalore BTMLA ,Marathahalli
Hi Thomas,
DeleteI am not aware of a captcha plugin. I have not seen anybody using that in this platform.
This comment has been removed by the author.
ReplyDeleteFor Devops Training in Bangalore visit : Devops training in Bangalore
ReplyDelete
ReplyDeleteمكافحة حشرات بالخبر افضل شركة مكافحة حشرات بالخبر
مكافحة حشرات بمكة افضل شركة رش حشرات بمكة
مكافحة حشرات بالمدينة المنورة افضل شركة رش حشرات بالمدينة المنورة
مكافحة حشرات بالدمام افضل شركة مكافحة حشرات بالدمام
I am really happy with your blog because your article is very unique and powerful for new reader.
ReplyDeleteaws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore
python Training in Bangalore
aws Training in Bangalore
Such great information for blogger iam a professional blogger thanks…
ReplyDeleteLooking for Hadoop Admin Training in Bangalore, learn from Softgen Infotech provide Hadoop Admin Training on online training and classroom training. Join today!
It is amazing and wonderful to visit your site.Thanks for sharing this information,this is useful .Manual Testing Training in Bangalore
ReplyDeleteI have read your blog its very attractive and impressive. I like it your blog. SELENIUM training in bangalor
ReplyDeleteGreat post!I am actually getting ready to across this information,i am very happy to this commands.Also great blog here with all of the valuable information you have.Well done,its a great knowledge.DOTNET training in bangalore
ReplyDeleteThanks for one marvelous posting! I enjoyed reading it; you are a great author. I will make sure to bookmark your blog and may come back someday. I want to encourage that you continue your great post.Microsoft Dynamics CRM Training in Bangalore
ReplyDelete
ReplyDeleteThank you for your post. This is excellent information. It is amazing and wonderful to visit your site.windows azure cloud computing training in bangalore
Really it was an awesome article,very interesting to read.You have provided an nice article,Thanks for sharing.
ReplyDeleteaws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore
python Training in Bangalore
aws Training in Bangalore
really it is an awesome information keep on doing...
ReplyDeletehttps://www.acte.in/angular-js-training-in-chennai
https://www.acte.in/angular-js-training-in-annanagar
https://www.acte.in/angular-js-training-in-omr
https://www.acte.in/angular-js-training-in-porur
https://www.acte.in/angular-js-training-in-tambaram
https://www.acte.in/angular-js-training-in-velachery
wonderful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article.Thanks for sharing such a good blog. You’re doing a great job. Keep posting like this useful info !! DevOps Training in Chennai | DevOps Training in anna nagar | DevOps Training in omr | DevOps Training in porur | DevOps Training in tambaram | DevOps Training in velachery
ReplyDeleteThis is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.keep update your post
ReplyDeleteAngularJS training in chennai | AngularJS training in anna nagar | AngularJS training in omr | AngularJS training in porur | AngularJS training in tambaram | AngularJS training in velachery
This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.keep update your post
ReplyDeleteAngularJS training in chennai | AngularJS training in anna nagar | AngularJS training in omr | AngularJS training in porur | AngularJS training in tambaram | AngularJS training in velachery
Really it is very useful for us..... the information that you have shared is really useful for everyone. If someone wants to know about
ReplyDeleteEHS Software and Health and Safety Software I think this is the right place for you. PHP Training in Chennai | Certification | Online Training Course | Machine Learning Training in Chennai | Certification | Online Training Course | iOT Training in Chennai | Certification | Online Training Course | Blockchain Training in Chennai | Certification | Online Training Course | Open Stack Training in Chennai |
Certification | Online Training Course
I love the way you post this blog its mindblowing. Thanks for the sharing valuable post it has all thing which is necessary to understand for a new person.
ReplyDeletedata science training in chennai
data science training in tambaram
android training in chennai
android training in tambaram
devops training in chennai
devops training in tambaram
artificial intelligence training in chennai
artificial intelligence training in tambaram
Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging
ReplyDeletejava training in chennai
java training in porur
aws training in chennai
aws training in porur
python training in chennai
python training in porur
selenium training in chennai
selenium training in porur
I like the helpful info you supply in your articles. I’ll bookmark your weblog and take a look at once more here regularly. I am relatively certain I will learn a lot of new stuff right here! Good luck for the following!
ReplyDeletesap training in chennai
sap training in velachery
azure training in chennai
azure training in velachery
cyber security course in chennai
cyber security course in velachery
ethical hacking course in chennai
ethical hacking course in velachery
ReplyDeleteIt is amazing and wonderful to visit your site.Thanks for sharing this information,this is useful
angular js training in chennai
angular js training in annanagar
full stack training in chennai
full stack training in annanagar
php training in chennai
php training in annanagar
photoshop training in chennai
photoshop training in annanagar
This article is really helpful for me. I am regular visitor to this blog. Share such kind of article more in future. Personally i like this article a lot and you can have a look at my services also: I was seriously search for a Salesforce training institutes in ameerpet which offer job assistance and Salesforce training institutes in Hyderabad who are providing certification material. It's worth to join Salesforce training institutes in India because of their real time projects material and 24x7 support from customer desk. You can easily find the best Salesforce training institutes in kukatpally kphb which are also a part of Pega training institutes in hyderabad. This is amazing to join Data science training institutes in ameerpet who are quire popular with Selenium training institutes in ameerpet and trending coureses like Java training institutes in ameerpet and data science related programming coures python training institutes in ameerpet If you want HCM course then this workday training institutes in ameerpet is best for you to get job on workday.
ReplyDeleteGood Post! , it was so good to read and useful to improve my knowledge as an updated one, keep blogging.After seeing your article I want to say that also a well-written article with some very good information which is very useful for the readers....thanks for sharing it and do share more posts likethis. https://www.3ritechnologies.com/course/data-science-online-training/
ReplyDeleteWow ! what an interesting blog. Thanks for sharing this information. Your information is really informative for us.
ReplyDeleteAngular js Training in Chennai
Angular js Training in Velachery
Angular js Training in Tambaram
Angular js Training in Porur
Angular js Training in Omr
Angular js Training in Annanagar
Nice article.
ReplyDeleteamazon web services aws training in chennai
microsoft azure course in chennai
workday course in chennai
android course in chennai
ios course in chennai
Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
ReplyDeletesalesforce training in chennai
software testing training course in chennai
robotic process automation rpa training in chennai
blockchain training in chennai
devops training in chennai
very nice blogs!!! i have to learning for lot of information for this sites...Sharing for wonderful information.Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing.
ReplyDeleteIELTS Coaching in chennai
German Classes in Chennai
GRE Coaching Classes in Chennai
TOEFL Coaching in Chennai
Spoken english classes in chennai | Communication training
This is a Great work and it is a very innovative blog. Well done!
ReplyDeleteGo Lang Training in Chennai
Google Cloud Training in Chennai
Google Cloud Online Training
Go Lang Course in Chennai
I am really happy with your blog because your article is very unique and powerful for new.
ReplyDeleteDevops Training Institute in Pune
Devops Training in Pune
very clearly explained thanks for sharing !
ReplyDeleteTALLY TRAINING IN CHENNAI
TALLY TRAINING INSTITUTE IN CHENNAI
TALLY ERP 9 CLASSES IN CHENNAI
TALLY COURSE IN CHENNAI
GST TALLY TRAINING INSTITUTE IN CHENNAI
TALLY CLASSES IN CHENNAI
BEST TALLY TRAINING CENTER IN CHENNAI
TALLY CERTIFICATION COURSE IN CHENNAI
TALLY CLASSES IN CHENNAI
BEST TALLY TRAINING COURSES IN CHENNAI
BEST TALLY ERP 9 TRAINING IN CHENNAI
TALLY ERP 9 COURSE IN CHENNAI
COMPANY ACCOUNTS TRAINING INSTITUTE IN CHENNAI
COMPANY ACCOUNTS TRAINING IN CHENNAI
ACCOUNTING COURSES IN CHENNAI
ACCOUNTS TRAINING CENTER IN CHENNAI
GST TRAINING INSTITUTE IN CHENNAI
GST CLASSES IN CHENNAI
GST TRAINING COURSES IN CHENNAI
GST CERTIFICATION COURSE IN CHENNAI
TALLY GST CERTIFICATION TRAINING IN CHENNAI
BEST TAXATION TRAINING IN CHENNAI
TAXATION COURSE IN CHENNAI
TAXATION CLASSES IN CHENNAI
INCOME TAX CONSULTANT COURSE IN CHENNAI
BEST TALLY TRAINING IN CHENNAI&VADAPALANI
BEST TALLY TRAINING COURSES WITH 100% JOB PLACEMENTS & CERTIFICATION
great!very useful article thanks for sharing
ReplyDeleteJava training institute in Chennai
Java training in Chennai
Best Java courses institutes
Java training in Chennai with 100% placements
Best Java training institute in Chennai
ONLINE JAVA TRAINING INSTITUTE IN CHENNAI
BEST JAVA TRAINING IN CHENNAI & VADAPALANI
CORE JAVA/J2EE TRAINING IN CHENNAI
BEST NO.1 JAVA TRAINING INSTITUTE IN CHENNAI & VADAPALANI
JAVA COURSE IN CHENNAI
JAVA CLASS IN CHENNAI
JAVA CLASSES IN CHENNAI
BEST JAVA TRAINING CENTER IN CHENNAI
JAVA CERTIFICATION COURSE IN CHENNAI
BEST JAVA TRAINING COURSES WITH 100% JOB PLACEMENTS & CERTIFICATION
instagram takipçi satın al
ReplyDeleteaşk kitapları
tiktok takipçi satın al
instagram beğeni satın al
youtube abone satın al
twitter takipçi satın al
tiktok beğeni satın al
tiktok izlenme satın al
twitter takipçi satın al
tiktok takipçi satın al
youtube abone satın al
tiktok beğeni satın al
instagram beğeni satın al
trend topic satın al
trend topic satın al
youtube abone satın al
instagram takipçi satın al
beğeni satın al
tiktok izlenme satın al
sms onay
youtube izlenme satın al
tiktok beğeni satın al
sms onay
sms onay
perde modelleri
instagram takipçi satın al
takipçi satın al
tiktok jeton hilesi
instagram takipçi satın al
pubg uc satın al
sultanbet
marsbahis
betboo
betboo
betboo
takipçi satın al
ReplyDeletetakipçi satın al
takipçi satın al
Great Content. Thanks for sharing this valuable information.
ReplyDeleteHybrid Cloud Services
Hybrid Cloud Hosting
marsbahis
ReplyDeletebetboo
sultanbet
marsbahis
betboo
sultanbet
Nice informative content. Thanks for sharing such worthy information.
ReplyDeleteAsp.net MVC Hosting
Advantages of MVC
The article you've shared here is fantastic because it provides some excellent information that will be incredibly beneficial to me. Thank you for sharing that. Keep up the good work. Metal Precision Casting
ReplyDeleteseo fiyatları
ReplyDeletesaç ekimi
dedektör
instagram takipçi satın al
ankara evden eve nakliyat
fantezi iç giyim
sosyal medya yönetimi
mobil ödeme bozdurma
kripto para nasıl alınır
Thanks for this blog keep sharing your thoughts like this...
ReplyDeleteWhat is MVC
Advantages of MVC Architecture
Thanks for this blog keep sharing your thoughts like this...
ReplyDeleteWhat is Spring
Features of Spring Framework
bitcoin nasıl alınır
ReplyDeletetiktok jeton hilesi
youtube abone satın al
gate io güvenilir mi
referans kimliği nedir
tiktok takipçi satın al
bitcoin nasıl alınır
mobil ödeme bozdurma
mobil ödeme bozdurma
mmorpg oyunlar
ReplyDeleteInstagram takipci satın al
Tiktok Jeton Hilesi
TİKTOK JETON HİLESİ
antalya saç ekimi
referans kimliği nedir
İNSTAGRAM TAKİPÇİ SATIN AL
Metin2 pvp serverlar
instagram takipçi satın al
perde modelleri
ReplyDeletemobil onay
mobil odeme bozdurma
Nft Nasıl Alınır
Ankara evden eve nakliyat
Trafik Sigortası
Dedektor
web sitesi kurma
ASK KİTAPLARİ
ataşehir alarko carrier klima servisi
ReplyDeleteçekmeköy daikin klima servisi
ataşehir daikin klima servisi
maltepe toshiba klima servisi
kadıköy toshiba klima servisi
maltepe beko klima servisi
kadıköy beko klima servisi
kartal lg klima servisi
kartal alarko carrier klima servisi
Good
ReplyDeletehttps://www.digisnare.com/
SIM cards are usually specific to a particular carrier, such as AT&T, Verizon, or Sprint. They can also be specific to a particular country. For example, a SIM card from the United Kingdom will not work in a device from the United States. Travel SIM Card
ReplyDeleteVray 6.00.05 Crack is a commercial plug-in for third-party developers' 3D computer graphics software programs. VRay 6.00.05 Crack
ReplyDeleteBirthday Wishes For Older Brother — Happy Birthday dear brother, wishing you a fantastic one! I am grateful you are my brother because you have .https://wishesquotz.com/birthday-wishes-for-brother/
ReplyDeleteSuccess Write content success. Thanks.
ReplyDeletekıbrıs bahis siteleri
betmatik
deneme bonusu
kralbet
betturkey
canlı slot siteleri
canlı poker siteleri
Good content. You write beautiful things.
ReplyDeletesportsbet
taksi
mrbahis
vbet
vbet
sportsbet
mrbahis
hacklink
korsan taksi
شركة كشف تسربات المياه
ReplyDeleteشركة جلي بلاط