Java EE 7 with Angular JS – CRUD, REST, Validations – Part 2

posted by Roberto Cortez on

This is the promised follow up to the Java EE 7 with Angular JS – Part 1. It took longer than I expect (to find the time to prepare the code and blog post), but it’s finally here!

The Application

The original application in Part 1 it’s only a simple list with pagination and a REST service that feeds the list data.

Java EE 7 - Angular - List

In this post we’re going to add CRUD (Create, Read, Update, Delete) capabilities, bind REST services to perform these operations on the server side and validate the data.

The Setup

The Setup is the same from Part 1, but here is the list for reference:

The Code

Backend – Java EE 7

The backend does not required many changes. Since we want the ability to create, read, update and delete, we need to add the appropriate methods in the REST service to perform these operations:

The code is exactly as a normal Java POJO, but using the Java EE annotations to enhance the behaviour. @ApplicationPath("/resources") and @Path("persons") will expose the REST service at the url yourdomain/resources/persons (yourdomain will be the host where the application is running). @Consumes(MediaType.APPLICATION_JSON) and @Produces(MediaType.APPLICATION_JSON) accept and format REST request and response as JSON.

For the REST operations:

Annotation / HTTP MethodJava MethodURLBehaviour
@GET / GETlistPersonshttp://yourdomain/resources/personsReturns a paginated list of 10 persons.
@GET / GETgetPersonhttp://yourdomain/resources/persons/{id}Returns a Person entity by it’s id.
@POST / POSTsavePersonhttp://yourdomain/resources/personsCreates or Updates a Person.
@DELETE / DELETEdeletePersonhttp://yourdomain/resources/persons/{id}Deletes a Person entity by it’s id.

The url invoked for each operations is very similar. The magic to distinguish which operation needs to be called is defined in the HTTP method itself when the request is submitted. Check HTTP Method definitions.

For getPerson and deletePerson note that we added the annotation @Path("{id}") which defines an optional path to call the service. Since we need to know which object we want to get or delete, we need to indicate the id somehow. This is done in the service url to be called, so if we want to delete the Person with id 1, we would call http://yourdomain/resources/persons/1 with the HTTP method DELETE.

That’s it for the backend stuff. Only 30 lines of code added to the old REST service. I have also added a new property to the Person object, to hold a link to image with the purpose of displaying an avatar of the person.

UI – Angular JS

For the UI part, I’ve decided to split it into 3 sections: the grid, the form and the feedback messages sections, each with its own Angular controller. The grid is mostly the same from Part 1, but it did require some tweaks for the new stuff:

Grid HTML

Nothing special here. Pretty much the same as Part 1.

Grid Angular Controller

A few more attributes are required to configure the behaviour of the grid. The important bits are the data: 'persons.list' which binds the grid data to Angular model value $scope.persons, the columnDefs which allow us to model the grid as we see fit. Since I wanted to add an option to delete each row, I needed to add a new cell which call the function deleteRow when you click in cross icon. The afterSelectionChanges function is required to update the form data with the person selected in the grid. You can check other grid options here.

The rest of the code is self-explanatory and there is also a few comments in there. A special note about $rootScope.$broadcast: this is used to dispatch an event to all the other controllers. This is a way to communicate between controllers, since the grid, form and feedback messages have separate controllers. If everything was in only one controller, this was not required and a simple function call would be enough. Another possible solution if we want to keep the multiple controllers, would be to use Angular services. The used approach seems much cleaner since it separates the application concerns and does not require you to implement additional Angular services, but it might be a little harder to debug if needed.

Form HTML

Here is the looks:

JavaEE 7 - Angular - Form

A lot of codeis for validation purposes, but lets look into this a bit more in detail: each input element binds its value to person.something. This allows to model the data between the HTML and the Javascript controller, so we can write $scope.person.name in our controller to get the value filled in the form input with name, name. To access the data inside the HTML form we use the form name personForm plus the name of the input field.

HTML5 have its own set of validations in the input fields, but we want to use the Angular ones. In that case, we need to disable form validations by using novalidate at the form element. Now, to use Angular validations, we can use a few Angular directives in the input elements. For this very basic form, we only use required, ng-minlength and ng-maxlength, but you can use others. Just look into the documentation.

Angular assigns CSS classes based on the input validation state. To have an idea, these are the possible values:

StateCSSOn
validng-validWhen the field is valid.
invalidng-invalidWhen the field is invalid.
pristineng-pristineWhen the field was never touched before.
dirtyng-dirtyWhen the field is changed.

These CSS classes are empty. You need to create them and assign them styles in an included CSS sheet for the application. Instead, we’re going to use styles from Bootstrap which are very nice. For them to work, a few additional classes need to be applied to the elements. The div element enclosing the input needs the CSS class form-group and the input element needs the CSS class form-control.

To display an invalid input field we add ng-class="{'has-error' : personForm.name.$invalid && personForm.name.$dirty}" to the containing input div. This code evaluates if the name in the personForm is invalid and if it’s dirty. It the condition verifies, then the input is displayed as invalid.

Finally, for the form validation messages we need to verify the $error directive for each of the inputs and types of validations being performed. Just add ng-show="personForm.name.$error.minlength" to an HTML display element with a message to warn the user that the name input field is too short.

Form Angular Controller

For the form controller, we need the two functions that perform the operations associated with the button Clear and the button Save which are self-explanatory. A quick note: for some reason, Angular does not clear input fields which are in invalid state. I did found a few people complaining about the same problem, but I need to investigate this further. Maybe it’s something I’m doing wrong.

REST services are called using save and delete from the $resource object which already implement the correspondent HTTP methods. Check the documentation. You can get a $resource with the following factory:

The rest of the controller code, are functions to pickup the events created by the grid to load the person data in the form and delete the person. This controller also create a few events. If we add or remove persons, the grid needs to be updated so an event is generated requesting the grid to be updated.

Feedback Messages HTML

This is just the top section of the application, to display success or error messages based on save, delete or server error.

Feedback Messages Angular Controller

This is the controller that push the messages to the view. Listens to the events created by the grid and the form controllers.

The End Result

Uff.. that was a lot of code and new information. Let’s see the final result:

JavaEE 7 - Angular - Full

There is also a live version running in http://javaee7-angular.radcortez.cloudbees.net, thanks to Cloudbees. It may take a while to open if the cloud instances is hibernated (because of no usage).
Unfortunately, Cloudbees stopped application hosting, but you can try using Codenvy in the following URL: https://codenvy.com/f?id=3qe4qr7mb8i86lpe. Check the post: Codenvy setup to demo applications using Docker: Java EE 7 with Angular.

Resources

You can clone a full working copy from my github repository and deploy it to Wildfly. You can find instructions there to deploy it. Should also work on Glassfish.

Java EE – Angular JS Source

Since I may modify the code in the future, you can download the original source of this post from the release 3.0. In alternative, clone the repo and checkout the tag from release 3.0 with the following command: git checkout 3.0.

Check also:

Final Thoughts

  • The form validation kicks in right after you start typing. Angular 1.3 will have an on blur property to validate only after loosing focus, but I’m still using Angular 1.2.x.
  • I have to confess that I found the validation code a bit too verbose. I don’t know if there is a way to simplify it, but you shouldn’t need to add each message validation to each input.
  • A few things are still lacking here, like parameters sanitisation or server side validation. I’ll cover those in a next blog post.

This was a very long post, actually the longest I’ve wrote on my blog. If you reached this far, thank you so much for your time reading this post. I hope you enjoyed it! Let me know if you have any comments.

Comments ( 50 )

  1. ReplyJoao

    Great post! Been working on some stuff using Angular, but haven’t mixed it with Java yet.

    A suggestion for next time: don’t leave the Java imports out of the snippets. I find them useful when reading Java code, maybe some other people do too.

    • ReplyRoberto Cortez

      Hi João. Thank you so much for your feedback. I’m glad you liked the post. Don’t worry, I can fix this right now. I just added the imports to the Java code.

  2. ReplyJameel Ahamed

    Hi Roberto Cortez, please send angular js frontend and java backend simple application. login controller and full single page application controller example pls send Roberto Cortez.

  3. ReplyJameel Ahamed

    I require an software like tally and I have been develop customer communication form.
    In that application Admin want to send remainder message to user (sms) like way2sms.
    Once admin collect user number from database and send automatic message through mobile in online application.
    Let me know any free URL to update this concept kindly mention that code details (.Net programming language).

  4. ReplyRoberto Cortez

    Hi Jameel,

    I’m not sure if I understand what you require. Do you want the code sample from this post? It’s in the post Resources section: https://github.com/radcortez/javaee7-angular

  5. Replyjameel

    I have been develop customer communication form.
    In that application Admin want to send remainder message to user (sms) like way2sms.
    Once admin collect user number from database and send automatic message through mobile in online application.
    Let me know any free URL to update this concept kindly mention that code details (.Net programming language). pls send asp.net sms application pls help….

    • ReplyRoberto Cortez

      Hi Jameel,

      I’m sorry, but I’m not a specialist in .Net. I can recommend you a few people instead. Is that ok?

      Cheers,
      Roberto

  6. ReplyJameel Ahamed

    Ok….

  7. ReplyJameel Ahamed

    please send point of sale application(POS) using angular js front end and java back end…

  8. ReplyJameel Ahamed

    Ok thanks. please one help, can you send ERP application and fully accounts maintable application. pls help Roberto.

  9. ReplyDreyk

    Hello,

    I don’t see here where it’s the database connection? I’m pretty new in AngularJs and Jersey. How can I connect my database here and change some attributes ?

    • ReplyRoberto Cortez

      Hi Dreyk,

      Thank you for reading my blog.

      In fact, the datasource used in the application is the default one from the application server. This uses a new features of Java EE 7 called Default Datasources. You can see additional information here and here.

  10. Replytaysay

    Great work, Radcortez. God bless you loads for caring to share.

  11. ReplyAnas

    Hello,
    Great post, but I want to work with Tomcat 8 and MySQL database. How can I connect my database here ?!

    • ReplyRoberto Cortez

      Hi Anas,

      Thank you! For Tomcat it going to be slightly different, because it doesn’t support Java EE. Have you ever consider moving to TomEE? It’s Tomcat plus Java Enterprise Edition. I can help you set up things there.

  12. ReplyJames

    Hi,
    Thanks a lot for these nice tips. It’s great!
    Could I know your opinions about angularfaces?
    Regards

    • ReplyRoberto Cortez

      Hi James,

      Thank you for your feedback. Unfortunately I’ve never used angularfaces before, so I can’t really have an opinion about it. I’m sorry I couldn’t help.

      Cheers,

  13. Replymnpoonia

    Thanks for the wonderful post. I am stuck with image url link. Not able to save a new record because of that. How to provide a image link for avatar?

    • Replymnpoonia

      I mean can’t we give local image url for that?

      • ReplyRoberto Cortez

        Hi mnpoonia,

        Thank you so much for your feedback.

        Currently it doesn’t support local images, because I had no time to do it when I was working on the code. Wouldn’t you consider to implement it and submit a pull request? 🙂

  14. ReplyAmsidh Lokhande

    Thanks Roberto Cortez,
    This code and your earlier code part 1 helps me lot to understand angularjs very well. The back end part I converted to Spring Rest Controller and connected to my won database through hibernate and it is working fine.Thanks a lot posting such blogs on internet and helping others to understand the new technology like angaularjs.

    • ReplyRoberto Cortez

      Hi Amsidh,

      Thank you very much for your comment and your feedback.

      I’m very happy that my post helped you. How about sharing your work with us? 🙂

      Cheers,
      Roberto

  15. ReplySteve B

    Thanks for such a useful and relevant post! I was hoping to see the running example (to help me debug some errors I am getting in the Angular code). When I click your link to http://javaee7-angular.radcortez.cloudbees.net, I get a server error. Is this service discontinued or has the Url changed? Is there anywhere else I can see your fine code in action?

    Thank You,
    Steve B.

    • ReplySteve B

      …further…I especially am trying to identify what versions of the .js and .css libraries you are using in the of the index.html? The bower-install does not work on my windows, and I do not know anything about npm, bower, or grunt to debug why that is failing. I really just need to figure out these libraries.

      Thanks Again!

      • ReplyRoberto Cortez

        Hi Steve,

        This should be what you are looking for:

        If you are using the latest version of the sample, which you should be, you don’t need to worry about Bower, NPM or Grunt. They are just used to update stuff if needed, but all the files should be in the repo for the sample to work.

        Let me know if you have any problem.

        Cheers,
        Roberto

    • ReplyRoberto Cortez

      Hi Steve,

      Thank you for the feedback. Unfortunately Cloudbees.net stopped offering the hosting so the url doesn’t work anymore. I’ll update the post. In the meanwhile, you can try the sample here:
      https://codenvy.com/f?id=3qe4qr7mb8i86lpe

      Cheers,
      Roberto

  16. Replysam

    Hi Cortez,
    I am storing a image in the DB as a blob. How could I show this image in the UI when i load the particular image. any suggestions.

    Thanks in adavnce.

  17. ReplyLucas

    How i can run this project ?
    i trying with
    Java EE Luna

    • ReplyRoberto Cortez

      Hi Lucas,

      I’m not very familiar with Eclipse IDE, but it should work just by importing the pom.xml file from the project.

      Cheers,
      Roberto

  18. ReplyLucas

    # Java EE 7 – Angular – Sample Application #

    ## How to run ? ##

    ….

    * Run the command ‘grunt’ to download all the web dependencies and build an optimized version of the project.

    Hello Again, i have problem at run this command:
    “Stack trace:
    TypeError: Arguments to path.join must be strings
    at Object.win32.join (path.js:233:13)”

    Any idea ? ( i see some fix, but anyone work, sorry for my english).

    Thknx for help 😀

    • ReplyRoberto Cortez

      Hi Lucas,

      I suspect that this might be related with the node version. Which one are you using?

      • ReplyDmitry Smirnov

        Hi Roberto.

        Just’ve stuck in the same problem for an hour. It is worth to mention this problem and point that is solved in master branch.

        Reader probably will try code which match the article, and will stuck with versions problem.

        Thanks for fixing in the master version and for using angular-grid istead of old ng-grid.

        • ReplyRoberto Cortez

          Thank you for your feedback Dmitry.

          I guess I’ll have to review all posts and update them to match master.

          Cheers,
          Roberto

  19. ReplyDmitry Smirnov

    Hi, Roberto! Thank you for excellent intro to angular for java developer. Probably the best tutorial I could find for this topic.

    • ReplyRoberto Cortez

      Hi Dmitry,

      Thank you very much for reading and for your feedback.

      Cheers,
      Roberto

  20. ReplyLarslemos

    Thank you for this wonderful post.
    I used in JUG Hyderabad to give a AngularJS for Java Developers and they loved it.
    Keep up the good work

    • ReplyRoberto Cortez

      Hi Larslemos,

      Thank you very much for your comment and I’m glad that my work could help you.

      Cheers,
      Roberto

  21. Replyfrancoj22

    Hi , first thanks so much .

    I tried to run the example given the url
    and i got this error. Any idea. I tried in a different computer as well.

    Unable to retrieve the resources from the runner.: {“message”:”Run action for this workspace is locked”}

    • ReplyRoberto Cortez

      Hi Fraco,

      I think the account might have run out of free memory resources to run the container. I’ll have a look.

      Thanks!

  22. ReplyLucas De Cól

    Hello, i have this error, any idea ? .

    C:\Users\Lucas De Cól\git\javaee7-angular>mvn clean install
    [INFO] Scanning for projects…
    [INFO]
    [INFO] ————————————————————————
    [INFO] Building javaee7-angular 3.6
    [INFO] ————————————————————————
    [INFO]
    [INFO] — maven-clean-plugin:2.5:clean (default-clean) @ javaee7-angular —
    Downloading: https://repo.maven.apache.org/maven2/org/apache/maven/maven-plugin-api/2.0.6/maven-plugin-api-2.0.6.jar
    [INFO] ————————————————————————
    [INFO] BUILD FAILURE
    [INFO] ————————————————————————
    [INFO] Total time: 1.366 s
    [INFO] Finished at: 2016-04-13T23:35:22-03:00
    [INFO] Final Memory: 6M/16M
    [INFO] ————————————————————————
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clean) on project javaee7-angular: Execution default-clean of goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean failed: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Could not transfer artifact org.apache.maven:maven-plugin-api:jar:2.0.6 from/to central (https://repo.maven.apache.org/maven2): repo.maven.apache.org: Unknown host repo.maven.apache.org -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginResolutionException

    • ReplyRoberto Cortez

      Hi Lucas,

      Thanks for reading!

      Looking into your log, I’ve noticed: “Unknown host repo.maven.apache.org”

      Seems that you are not able to reach the Maven repo from your machine? Can you try to access the address http://repo.maven.apache.org/maven2/ with a web browser? If you can’t, there a connectivity problem somewhere. Might be a firewall issue. You need to be able to access the repo to download the required libraries.

      Cheers,
      Roberto

  23. Replynani

    Hi Roberto Cortez,

    this is nani from india . Thank you for excellent intro to angular for java developer. can you help me . plz send me sample ERP(min three module, like profile, tranction,batch) project java,angularjs,mysql, using eclipse IDE ,tomcat server .

    • ReplyRoberto Cortez

      Hi nani,

      Thank you. I’m happy to help if you need something, but at this time I’m unable to do it.

      Cheers,

  24. Replyyair

    thank you very much Roberto, there is something that still can not understand, How is it that relates to or communicates the js with methods java?.
    Again thank you very much.

    • ReplyRoberto Cortez

      It’s uses HTTP Rest. Java exposes the services as REST and JS is able to call them through HTTP, by doing a regular call. You can try opening up in your browser direct links from the HTTP Rest so you can see their response.

  25. ReplyImran Shaikh

    Hi Roberto Cortez,

    You posts are awesome.
    I helped me alot.

    Thanks for such wonderfull posts.

Leave a Reply to Roberto Cortez Cancel reply

Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>