Making an address book application using JAVA - java

I am a Java beginner and am going to make a small address book client program using java swing.
And my goal is implementing 3-tier architecture. (No sql queries are in client program)
What would be the best approach for this?
I thought (Java EE)--(XML or JSON)--(MySQL) would be the one, but isn't it too hard for beginner? :)
What else could be?
Thank you for reading my question!

Depends on what you mean by Java EE (J2EE is 1999 vintage terminology - drop the "2", please.)
You can write a web-based address book using servlets and JSPs. If you want a relational database you can use JDBC, but it's possible to make do without that.
You should make your data access layer interface-based. That will let you change the implementation without affecting clients.
Your UI will be JSPs. You'll have a front controller servlet that will accept requests, figure out how to handle them, and send the response to the next view.

Java EE contains many technologies that can make building this type of application easier:
EJB - Use a session bean to create your application.
JAX-RS - Expose your session bean as a RESTful service via XML and JSON messsages.
JAXB - Handles the conversion of your model objects to/from XML and JSON
JPA - Handles storing your model objects in the database without you writing JDBC code
If this sounds like a lot, look at how little code you need to write:
package org.example;
import java.util.List;
import javax.ejb.*;
import javax.persistence.*;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
#Stateless
#LocalBean
#Path("/customers")
public class CustomerService {
#PersistenceContext(unitName="CustomerService",
type=PersistenceContextType.TRANSACTION)
EntityManager entityManager;
#POST
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void create(Customer customer) {
entityManager.persist(customer);
}
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Path("{id}")
public Customer read(#PathParam("id") long id) {
return entityManager.find(Customer.class, id);
}
#PUT
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void update(Customer customer) {
entityManager.merge(customer);
}
#DELETE
#Path("{id}")
public void delete(#PathParam("id") long id) {
Customer customer = read(id);
if(null != customer) {
entityManager.remove(customer);
}
}
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Path("findCustomersByCity/{city}")
public List<Customer> findCustomersByCity(#PathParam("city") String city) {
Query query = entityManager.createNamedQuery("findCustomersByCity");
query.setParameter("city", city);
return query.getResultList();
}
}
For a Full Example
Part 1 - The Database
Part 2 - Mapping the Database to JPA Entities
Part 3 - Mapping JPA entities to XML (using JAXB)
Part 4 - The RESTful Service
Part 5 - The Client

You say you are a Java beginner, the answer to your dilemma IMO depends on your experience with other languages (and programming in general). There are alot of layers in a web application, meaning many things can go wrong, so I think it is best to start with the easy stuff and work your way up. SO... I would recommend not getting carried away with XML, JSON, MVC, etc on your first app. You can still write a great application and learn alot of stuff by keeping it a little lower tech, such as using JSP pages that use JavaBeans and letting the beans handle the SQL, etc.
You can (and should) move on from there with AJAX, MVC architectures, etc.

Related

How do I share an interface between a graphql server and a graphql client

I am currently reevaluating a graphql stack at work. We iterate fairly quickly on our internal graphql API and the iterations get more and more painful to manage, especially for the consumers, due to breaking changes in the API. Therefore, I would like to pursue a code-first approach in java. By that I mean I want to share the classes for our domain model between the server side and client side. In addition, I want one or more java interfaces to define a set of public methods which returns objects of our domain model classes. The purpose of the interfaces is to make a contract or public API between the server and client to ensure both sides implements the contract. Our graphql API is the main product but I want to hide the API slightly and rather expose a java client.
Main objective: How to obtain a versioned graphql API hosted by a versioned server and a versioned reference client in java for customers of the graphql API. On new releases of the graphql API I want to be able to release a corresponding client and domain model.
So far i have been playing around with the Quarkus extensions quarkus-smallrye-graphql and quarkus-smallrye-graphql-client.
Interface
#GraphQLClientApi(configKey = "star-wars-typesafe")
public interface StarWarsClientApi {
List<Film> allFilms();
}
Client
#Path("/")
#ApplicationScoped
public class StarWarsResource {
#Inject
StarWarsClientApi client;
#GET
#Path("/typesafe")
#Produces(MediaType.APPLICATION_JSON)
#Blocking
public List<Film> getAllFilmsUsingTypesafeClient() {
return client.allFilms();
}
}
Server
#GraphQLApi
public class FilmResource implements StarWarsClientApi{
#Inject
GalaxyService service;
#Query()
#Description("Get all Films from a galaxy far far away")
public List<Film> allFilms() {
return service.getAllFilms();
}
}
Then I run into a AmbiguousResolutionException. Which I guess makes sense, even for me. Afterwards, I tried to define a Qualifier called #Client. Now I am facing a UnsatisfiedResolutionException. And by now my knowledge and creativity stops in regards to CDI.
Anyone who can pinpoint what I am doing wrong or suggest an alternative approach to achieve the main objective from above?
Interface
#GraphQLClientApi(configKey = "star-wars-typesafe")
#Client
public interface StarWarsClientApi {
List<Film> allFilms();
}
Client
#Path("/")
#ApplicationScoped
public class StarWarsResource {
#Inject #Client
StarWarsClientApi client;
#GET
#Path("/typesafe")
#Produces(MediaType.APPLICATION_JSON)
#Blocking
public List<Film> getAllFilmsUsingTypesafeClient() {
return client.allFilms();
}
}

Add Entire Protobuf Message to Model in Spring Boot

I'm starting to play around with Spring Boot to learn how it functions for a MVC web application.
At a high-level the goal is to have a controller that will handle GET requests by issuing a request to an external gRPC server which will return a Order protobuf message. The Order data will be added to the Model and served via a template with Thymeleaf.
I am new to the Spring framework as a whole so the approach is likely incorrect but what I was doing is:
#Controller
public class OrderController {
#GetMapping("/order")
public String getOrder(#RequestParam(name = "order_number") String orderNumber, Model model) {
// Code for getting Order proto message from external server here
model.addAttribute("name", Order.getDate());
model.addAttribute("total", Order.getTotal());
model.addAttribute("number", Order.getNumber());
....
return "order";
}
}
However, this seems pretty tedious (especially for larger messages). Is there something I am missing that would allow me to add these fields en-masse?
Sorry, I cannot comment on question (SO restriction), hence asking here - cannot you just put your order object in model (rather than individual fields) and access it's fields/methods in view (Thymeleaf)?
In controller
model.addAttribute("order", order);
in view, I am not sure as I have not used Thymeleaf but should be simillar to
<span th:text="${order.getName()}" />

Looking for the best way to share an interface between microservices with quarkus

I'm still quite new to microservices and have a few basic architectural questions that I can't get solved right now.
I'm using the Quarkus framework with the standard extensions like quarkus-resteasy and quarkus-rest-client for the realization.
The scenario:
I have an example of a "Persistence" service that I want to externally populate with data via a REST call in a dedicated Maven project.
#Path("/api/persistence")
#Products(MediaType.APPLICATION_JSON)
public class Persistence{
#Inject
EntityManager entityManager;
#POST
#Transactional
public Response create(PostDto postDto) {
Post post = toPostMapper.toResource(postDto);
entityManager.persist(post);
return Response.ok(postDto).status(201).build();
}
}
At the same time I would like to have a microservice DataGenerator which generates the corresponding data and passes it to the Persistence Service.
My problem : API sharing
Both services were created as Maven projects.
According to the tutorials I found the correct way would be to declare an interface (here called PersistenceApi) in the DataGenerator project like this
#Path("/api/persistence")
#Products(MediaType.APPLICATION_JSON)
#RegisterRestClient
public interface PersistenceApi {
#POST
#Transactional
public Response create(PostDto post) ;
}
This interface is then integrated into the DataGenerator service via #Inject, which leads to the following exemplary service.
#RequestScoped
#Path("/api/datagenerator")
#Products("application/json")
#Consumes("application/json")
public class DataGenerator{
#Inject
#RestClient
PersistenceApi persistenceApi
#POST
public void getPostExamplePostToPersistence() {
PostDto post = new PostDto();
post.setTitle("Find me in db in persistence-service")
persistenceApi.create(post);
}
}
I have the PersistenceService running locally on port 8181 and have added the following entry in the application.properties of the DataGenerator project so that the service can be found.
furnace.collection.item.service.PersistenceApi/mp-rest/url=http://localhost:8181
furnace.collection.item.service.PersistenceApi/mp-rest/scope=javax.inject.Singleton
I find it "wrong" to declare the interface in my DataGenerator, because at this point I don't notice when the api provided by the Persistence service changes. Accordingly one could come up with the idea to position the interface in the Persistence service, which is then implemented by my concrete Persistence implementation and leads to the following code.
#Path("/api/persistence")
#Products(MediaType.APPLICATION_JSON)
#RegisterRestClient
public class PersistenceApiImpl implements PersistenceApi {
#Inject
EntityManager entityManager;
#POST
#Transactional
public Response create(PostDto fruit) {
Post post = toPostMapper.toResource(fruit);
entityManager.persist(post);
return Response.ok(fruit).status(201).build();
}
}
In order to use them in my DataGenerator project, I would have to include the Persistence project as a dependency in my DataGenerator project, which sounds like a "monolith with extra steps" to me and therefore feels wrong in terms of "separation of concerns".
I have tried the following approach:
I created another Maven project called PersistenceApi which only contains the corresponding PersistenceApi. This PersistenceApi project was then included as a dependency in both the "Persistence" and "DataGenerator" projects. In the "Persistence"-Project I implement the service from the example above and try to address the corresponding interface in the "DataGenerator"-Project via #Inject.
Unfortunately this does not work. When I'm building the service, I get the message that the required dependency PersistenceApi, which I want to include via #Inject in the DataGenerator service, cannot be injected in the form of an UnsatisfiedResolutionException.
Now my questions:
I don't see what I'm missing here. Could you help me?
Is this kind of API-sharing with dedicated Api projects a viable way or is the "monolith with extra steps" approach really the way to go?
Thank you in advance.
Thats a common problem with microservices. Like in the book "Microservices: Grundlagen flexibler Softwarearchitekturen" by Eberhard Wolff (I saw that you are German too) i follow the idea that microservices should have the same coupling like the teams developing them and like the organization your developing it for(have a look at Conway's law). Therefore services of mostly independent teams should be developed independly and the api changes of one service should not affect another at the time of the update.
If you develop both services in your team then i think you can couple them the way you are doing it because you dont have to work together with other teams and there will be no huge overhead. Note that you will be forced to release both services together. If that is always ok for you then save your time and do it your way, if not have a look at API-Versioning:
I use api versioning so the old api is still reachable under "v1/" and the new one under "v2/". This way the team behind the other microservice has enough time to update their service.
Have a look at Domain-driven Design for different ways of integrating bounded contexts (=services) and the coupling consequences. Without API-Versioning you are forced to a partnership and you need to release together. Maybe you prefer Customer-Supplier or even conformist.
To test compatibility between both services have a look at consumer driven contracts and Pact. You can also generate open api files and track their changes but that will only help to notify people about changes.

RESTful Web Service using Netbeans and Java Issue

I'm new at Restful webservices and im trying to create a WS server to work with an android app. I'm using Netbeans and i followed this tuturial to get started (http://netbeans.org/kb/docs/websvc/rest.html) . I was able to successfully teste the basic features as explained in the tuturial. But now I am not able to add a new feature to the WS. Say I have a table in my DB called User. With the tuturial I can access the table Users by ID trhough the function
#GET
#Path("{id}")
#Produces(
{
"application/xml", "application/json"
})
public User find(#PathParam("id") Integer id)
{
return super.find(id);
}
The problem is if I want to get a User by its name for example. If I create a similar function like
#GET
#Path("{name}")
#Produces(
{
"application/xml", "application/json"
})
public User find(#PathParam("name") String name)
{
return super.find(name);
}
The server crashes. So my question is , what's the procedure to be able to get a User by other parameters different of id.
Thank you
Here there is a video of one hour long where you can see an implementation of a web-service front end that allows users to insert and also access database rows.
The principle should be the same, because web services are meant to serve inter-operable clients, doesn't mind if it is an android app or what ever.
In this video you will see how 2 parameters are used to form a query and fire it against an oracle database.
I think something that can help you would be an EJB to implement a CRUD facade.
I hope it helps: http://www.youtube.com/watch?v=0_0gGL2C1ys&feature=player_embedded

developing a webservice using java and mysql

I am not familiar with websrvices and mysql ..i followed this http://www.vogella.com/articles/REST/article.html tutorial and developed a RESTful web service in Java with the JAX-RS reference implementation Jersey.
I want to create an websrevice using eclipse which select the data from mysql database and display the result in xml format.
I got lots of sample developing webservices with PHP and mysql but i want to develop in java.
Please suggest me some good tutorial/links on this or idea which may help me. i want to use that webservice in my android application.
In the above example ,i am not getting where to put the connection string to establish the connection between MySQL database and java files.
Here is the TodoResource.java :
package de.vogella.jersey.jaxb;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import de.vogella.jersey.jaxb.model.Todo;
#Path("/todo")
public class TodoResource {
// This method is called if XMLis request
#GET
#Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
//#Produces( { MediaType.TEXT_XML })
public Todo getXML() {
Todo todo = new Todo();
todo.setSummary("This is my first todo");
todo.setDescription("This is my first todo");
todo.setMy_id(1);
return todo;
}
// This can be used to test the integration with the browser
#GET
#Produces( { MediaType.TEXT_XML })
public Todo getHTML() {
Todo todo = new Todo();
todo.setSummary("This is my first todo");
todo.setDescription("This is my first todo");
return todo;
}
}
I would start here : http://wiki.restlet.org/docs_2.1/13-restlet/21-restlet.html
You can create a java class/method that encapsulates the Business logic, for example a method like getData(DataFormat xml/html, whatData) which connects to the mysql database and retrieves records and then transforms it into required format, call this method within getXML() and getHTML()
Spring MVC makes REST based development very easy. Refer to this blog
The example you linked to does not actually make use of a database but uses in-memory Todo's to provide the data. In section 8 the author states
Create the following data model and a Singleton which serves as the
data provider for the model. We use the implementation based on an
enumeration.
The data model is the Todo class.
The data provider is the TodoDao enum. The purpose of TodoDao, is essentially to store Todo's in memory. In other words, it performs the function that would otherwise be done by a database.
What therefore needs to be done, is to:
Replace TodoDao with a database.
Map Todo to a table in the database.
To connect Java objects to a database, you can use an Object Relational Mapper (ORM), which can be achieved by using the Java Persistence API (JPA).
Therefore, to map Todo to a database table, it needs to be annotated with JPA annotations, thus creating a JPA Entity.
Have a look the accepted answer to REST/JSON Web Services Java EE Framework, it should shed some light on what needs to be done. Part 1 covers creating a database, while Part 2 covers creating and annotating JPA entities (Part 3 - JAXB Bindings for xml or json, Part 4 - The RESTFul Service, Part 5 - The Client).
If difficulties are still encountered, have a look at the answer I posted for Need to write a RESTful JSON service in Java, that should be suitable for someone who wants more nitty-gritty to, as a starting point, connect to a single table in a database and create a RESTful Web Service with JSON/XML representations using the following.
IDE: Eclipse IDE for Jave EE Developers (Kepler), comes with Maven built in
Database: MySQL (also makes use of MySQL Workbench)
Application Server: GlassFish 4.0
Java EE 7 (JAX-RS, JPA, JAXB, etc)
Any REST Client for testing: (eg Postman)

Categories