Win a copy of Transfer Learning for Natural Language Processing (MEAP) this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Paul Clapham
  • Devaka Cooray
  • Bear Bibeault
Sheriffs:
  • Junilu Lacar
  • Knute Snortum
  • Liutauras Vilda
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Piet Souris
Bartenders:
  • salvin francis
  • Carey Brown
  • Frits Walraven

Java app architecture directions?

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all. My goal is to develop an e learning app. The will use a MySQL database. The database will store user details (such as username, email etc) and also results (a result row contains userid, testid and score). By now I developed the GUI using JavaFX and also database operations. Here comes the problem: since the app will be multi user, from what I ve read it's not good to have database operations inside client app. So if anyone could tell me some directions on how could I separate the client app from server app. Does server means a REST API between client app and  database? I think there s not a good idea to have database operations coded into client application.. so I think the client app should only call some server methods, am I right?
 
Saloon Keeper
Posts: 11899
253
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sure, a REST API is one way to do it. You can use JAX-RS to communicate between the client and the web service. For the service, use the annotations defined in javax.ws.rs. You can create a client using ClientBuilder.

If you run the service in Tomcat, you can use Jersey as the JAX-RS implementation.

I've also found something called EclipseLink JPA-RS, which seems to be a technology for quickly setting up a web service for the sole purpose of interacting with a database. It might be just what you're looking for, but personally I'm wary of it because I don't like my web API to be so tightly coupled with the database.
 
Robert Ilin
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Sure, a REST API is one way to do it. You can use JAX-RS to communicate between the client and the web service. For the service, use the annotations defined in javax.ws.rs. You can create a client using ClientBuilder.

If you run the service in Tomcat, you can use Jersey as the JAX-RS implementation.

I've also found something called EclipseLink JPA-RS, which seems to be a technology for quickly setting up a web service for the sole purpose of interacting with a database. It might be just what you're looking for, but personally I'm wary of it because I don't like my web API to be so tightly coupled with the database.



So basically the web service acts as a 'server'? The server and the client app should be 2 different projects in Eclipse or in the same project? And another thing the content of the learning app will be generated dynamically based on some config files. Where to store these config files? I don t think it s a good idea to store them on the client side app because I don t want the client to access these files.

Thanks
 
Stephan van Hulst
Saloon Keeper
Posts: 11899
253
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Robert Ilin wrote:So basically the web service acts as a 'server'?


No. The word 'server' should be used to refer to a device or application that hosts services. In this discussion I will use the word 'server' to refer to Tomcat (or any other application container, such as WildFly or Glassfish), and I will use the word 'service' to refer to the application that you will write to handle client requests. People often use the word 'server' when they actually mean 'service'.

The server and the client app should be 2 different projects in Eclipse or in the same project?


Make 5 projects:

  • The core library that contains the business layer of your application. It contains classes such as Student, Exam and Score.
  • The web service API that contains the interface of your web service and all the classes that are necessary to communicate with it.
  • The web service implementation that implements the web service interface.
  • The client application that contains a proxy implementation of the web service interface that just forwards all method calls to the web service.
  • A parent project that aggregates the 4 projects above.

  • You should use Maven to set all of this up. If you have questions on how to set up any of these projects, please let us know.

    And another thing the content of the learning app will be generated dynamically based on some config files. Where to store these config files? I don t think it s a good idea to store them on the client side app because I don t want the client to access these files.


    You put them in some folder underneath the WEB-INF folder of the web service implementation project.
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Could you give me some suggestion for how to use Maven (or a tutorial)? I haven t used it before. And if the projects are separated, how will I access the classes from the library project let s say in the Client app?

    Thanks
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Maven's own documentation is well written. To start, read the first four pages that are linked to here. For more detailed information, read the two reference documents linked to at the bottom.

    After reading the quick start, try to create POMs for all 5 projects. This should roughly be the directory layout:

    The packaging for the parent POM (the one in the root project folder) should be 'pom'. The packaging for the learning-service-impl should be 'war'. The packaging for the other projects should be 'jar', but in that case you can just remove the <packaging> element, because 'jar' is the default.

    When you're done or when you're stuck, show us the results so we can help you along further.

    I strongly suggest NetBeans for Maven projects. NetBeans understands Maven projects out of the box, and also has good wizards for you to create new Maven projects.

    Robert Ilin wrote:And if the projects are separated, how will I access the classes from the library project let s say in the Client app?


    You can do this by declaring a dependency on the core library in the POM of the client application. The Maven user manual explains how to do this.
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    And one more thing. I was talking about those config files, basically those files will contain the learning material structured in chapters and lessons. I thought this is a good approach since if I want to modify some content I don t need to modify the code but only the files. So basically I thought about a mechanism in which the app will load these files and create some object stored in arrays (e.g a chapter object or a test object) and use it to draw the java fx interface whenever a resource is needed ( for example if the user access the learning section the app will use the chapters array which was created on startup and generate the java fx view dynamically). Is it a good approach to load all the content of the config files on startup or do you suggest a better approach? Or maybe a better approach for keeping the chapters and the tests? So basically in my approach, when the client app start it will call some server method to populate these arrays of objects and then iterate through it to draw the associated java fx view when needed.

    Thanks
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Robert Ilin wrote:I thought this is a good approach since if I want to modify some content I don t need to modify the code but only the files.


    Yes sounds good.

    and use it to draw the java fx interface whenever a resource is needed


    Yes. You'd have to create endpoints in your web service interface so that the client can retrieve the chapters/tests from the service and then display them in the user interface, but this is pretty standard application design.

    Is it a good approach to load all the content of the config files on startup or do you suggest a better approach?


    Honestly I'd just load the files every time you get a request from the client. This requires a lot less book keeping than loading things at startup, and it's often fast enough. Only if you find out by rigorous profiling that your application is too slow and one of the causes is that the files are being read on every request should you write code to optimize it.
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you. And could you please give me some directions or some good tutorials for developing a web service and a client using the web service? I haven t developed a web service before, but I have some experience with Java. And I don't know where to start. I would appreciate if you would give me some suggestions, maybe how to develop a simple web service to start with and then moving to my app..
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I can give you a quick start. You just need to tell me which application server you want to use. Tomcat is usually enough for most web applications.
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Tomcat is ok
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:I can give you a quick start. You just need to tell me which application server you want to use. Tomcat is usually enough for most web applications.


    Tomcat is ok. Can you provide me a quick start please?
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Let's say you have the following class in your core library:

    For now, please ignore the requireThat() methods. They are part of a private library I built, and you can replace them in your own code by doing something like this:

    In your Web Service API project, you add the following controller interface:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    In the Web Service API project, there is a separate package that contains the XML type definitions that are used to serialize the objects that your controller sends and receives. It contains classes like this:




     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The same package that contains your XML type definitions also contains an adapter so you can tell JAXB how to (de)serialize LocalDate, which it doesn't know by default:

    Now, you need to do a little bit of magic to configure more XML-related stuff in JAXB. In the same package as the XML type definitions, add a file package-info.java with the following contents:

    The @XmlAccessorType annotation tells JAXB that we don't want it to automatically serialize fields and properties in our XML type definitions, only the fields that we have explicitly annotated with @XmlElement and @XmlAttribute.

    The @XmlSchema annotation tells JAXB that all XML types in the com.example.learning.service.data package use the https://xmlns.learning.example.com/learning-service XML namespace by default. The UNQUALIFIED enum constants tell JAXB that we only want to use the namespace for our root elements (our requests and responses) and not for the attributes and elements contained by those root elements. This way, our requests look like this:
    And not like this:

    The @XmlSchemaTypes annotation tells JAXB what types to use when generating an XML schema from our classes. In this case we told it it needs to use xs:date whenever it encounters a LocalDate. The @XmlJavaTypeAdapters annotation tells JAXB HOW to serialize and deserialize certain types, using the adapter we created before.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Now that we have created our web service API, we can implement it in a separate project:


    The @ApplicationPath annotation tells JAX-RS what the root path of our REST API is. The @Path annotation tells JAX-RS what the subpaths of our controllers and actions are. You can use the @POST, @GET, @PUT and @DELETE annotations to specify the HTTP verb used to access a controller action.

    For instance, to access the registerStudent() action, you send a HTTP POST request to http://<host>/<context>/api/students. To remove the student with ID 2, you send a HTTP DELETE request to http://<host>/<context>/api/students/2.

    The @Consumes and @Produces annotations tell JAX-RS what media types to use for requests and responses. In this case, all content is sent and received as XML. You can change it to JSON if you want, and JAXB will just use your existing XML type definitions to reason what the JSON should look like.

    The @Singleton annotation is something I put on the controller just for this example. It tells JAX-RS to keep the controller in memory between requests, and to reuse it for each request. That way, the repository field will keep its value between requests.

    In a real application, don't make your controllers singleton and don't give them any fields that keep track of application state. Everything should be written to a database instead.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here is the POM I used for the web service API project:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here is the POM I used for the service implementation:

    Note that in both POMs above, I inherit dependency versions and scopes from the parent POM. I will post that one later. First I will explain why you need these dependencies in these projects:

    The service API depends on the application's core library and on jakarta.xml.bind-api. The latter contains the JAXB API that you can use to bind Java types to XML types.

    The service implementation depends on the service API, and so it also has transitive dependencies on the core library and on the JAXB API.

    It also depends on jakarta.inject-api for the @Singleton annotation. You can remove this dependency when you use a proper persistence layer instead of singleton controllers.

    The dependency on jakarta.servlet-api is not strictly necessary for the web service, because it doesn't use any classes or annotations from the Servlet API, but in order to run the application in a web container it needs a web deployment descriptor (web.xml). The Servlet specification says that the web descriptor is optional if we use at least the Servlet API version 3, so that's why we declare it here.

    jakarta.ws.rs-api is used for the JAX-RS annotations, the annotations that let you define your REST controllers (@Path, @GET, etc.).

    Finally, jaxb-runtime, jersey-container-servlet and jersey-hk2 are needed to provide runtime implementations of JAXB and JAX-RS, because jakarta.xml.bind-api and jakarta.ws.rs-api are just APIs and they don't contain implementations.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Finally, here is the parent POM.

    An important thing to note is that if you're using a full enterprise server (like WildFly or JBoss or WebSphere or something like that) you can set the scope of the jakarta.xml.bind-api and jakarta.ws.rs-api dependencies to provided, because they are already provided by the application server at runtime. They also don't need any of the dependencies marked as runtime, because they provide their own implementations. All those implementations are just provided for Tomcat, because it's a web container and not a full enterprise server.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    As a final note, this is NOT a complete REST API. If you want to be super RESTful, you need to add hypermedia to your responses, so that the client can discover at what locations it can access other resources or what actions it can perform currently. This is outside the scope of this discussion though. If you want to know more, the keyword to search for is HATEOAS.
     
    Robert Ilin
    Greenhorn
    Posts: 15
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you very much. Do you have an example of creating a client? And to keep the client in the end user app? Like just one instance? And from the client app I call the service methods?  And maybe a not so related question.. what will prevent the user from using the methods in the service and delete a user from the database with another id for example if I call service methods from user side?

    Thank you again
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 11899
    253
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    See your other topic for the client side.

    I'll see if I can come up with a security later this week.
     
    I found some pretty shells, some sea glass and this lovely tiny ad:
    Two software engineers solve most of the world's problems in one K&R sized book
    https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
      Bookmark Topic Watch Topic
    • New Topic