Why use JAX-RS / Jersey? - rest

Sorry, this questions sounds silly, but after developing some of my RESTful services using Jersey, I asked myself the question -- If REST is just an architecture, and not a protocol like SOAP, why do we need a specification like JAX-RS?
I actually googled for questions like "What is the difference between servlets and RESTful services over HTTP" and to sum up the community answers, I got:
RESTful service development (on Jersey) is an architecture, which inherently uses servlets.
JAX-RS compliant tools like Jersey provide easy marshalling-unmarshalling of XML/JSON data, helping the developers.
REST helps us use GET/POST/PUT/DELETE in a fashion that is far efficient than normal servlets.
According to these answers, I guess if I write a servlet which uses JAXB (for dealing with automatic serialization), and I efficiently use GET/POST/PUT/DELETE in my servlet code, I don't use a tool like Jersey, and hence JAX-RS.
I know I am terribly wrong passing this statement, please correct me.
PS: This doubt actually came in when I had to develop some RESTful services in PHP. After going on through some of the RESTful PHP codes, I realized they are just the same old PHP scripts, with some helper methods for handling XML/JSON.

Why use JAX-RS / Jersey?
Short Answer
Because it makes the development of RESTful services easier.
Long Answer
JAX-RS is a standard that makes it easy to create a RESTful service that can be deployed to any Java application server: GlassFish, WebLogic, WebSphere, JBoss, etc.
JAX-RS is part of Java EE, and when JAX-RS is used with other Java EE technologies it becomes even easier to create your RESTful service:
EJB - A session bean is used as the service implementation and also handles the transaction semantics.
JAX-RS - Used to expose the session bean as a RESTful service
JPA - Used to persist the POJOs to the database. Note how the EntityManager is injected onto the session bean.
JAXB - Used to convert the POJO to/from XML (in GlassFish it can also be used to convert the POJO to/from JSON). JAX-RS by default handles the interaction with the JAXB implementation.
Sample JAX-RS Service
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)
public void create(Customer customer) {
entityManager.persist(customer);
}
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("{id}")
public Customer read(#PathParam("id") long id) {
return entityManager.find(Customer.class, id);
}
#PUT
#Consumes(MediaType.APPLICATION_XML)
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)
#Path("findCustomersByCity/{city}")
public List<Customer> findCustomersByCity(#PathParam("city") String city) {
Query query = entityManager.createNamedQuery("findCustomersByCity");
query.setParameter("city", city);
return query.getResultList();
}
}
For More Information:
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-45.html

REST is an architecture, which inherently uses servlets.
No, it is not. REST is an architecture style which can be implemented using servlets, but does not inherently use them, nor inherently have anything to do with Java.
JAX-RS is a JSR Specification defining a Java API for RESTful Web Services.
Jersey is a specific implementation of JAX-RS.
As to whether to use Jersey or try to be compliant to the JAX-RS specification, that's sort of up to you. If it makes your work easier, great! If not no one's forcing you.

Related

How would you setup an JSF entity, service and backing bean [duplicate]

I'm trying to get used to how JSF works with regards to accessing data (coming from a spring background)
I'm creating a simple example that maintains a list of users, I have something like
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
Then the "controller" has something like
#Named(value = "userListController")
#SessionScoped
public class UserListController {
#EJB
private UserListService userListService;
private List<User> userList;
public List<User> getUserList() {
userList = userListService.getUsers();
return userList;
}
}
And the "service" (although it seems more like a DAO) has
public class UserListService {
#PersistenceContext
private EntityManager em;
public List<User> getUsers() {
Query query = em.createQuery("SELECT u from User as u");
return query.getResultList();
}
}
Is this the correct way of doing things? Is my terminology right? The "service" feels more like a DAO? And the controller feels like it's doing some of the job of the service.
Is this the correct way of doing things?
Apart from performing business logic the inefficient way in a managed bean getter method, and using a too broad managed bean scope, it looks okay. If you move the service call from the getter method to a #PostConstruct method and use either #RequestScoped or #ViewScoped instead of #SessionScoped, it will look better.
See also:
Why JSF calls getters multiple times
How to choose the right bean scope?
Is my terminology right?
It's okay. As long as you're consistent with it and the code is readable in a sensible way. Only your way of naming classes and variables is somewhat awkward (illogical and/or duplication). For instance, I personally would use users instead of userList, and use var="user" instead of var="u", and use id and name instead of userId and userName. Also, a "UserListService" sounds like it can only deal with lists of users instead of users in general. I'd rather use "UserService" so you can also use it for creating, updating and deleting users.
See also:
JSF managed bean naming conventions
The "service" feels more like a DAO?
It isn't exactly a DAO. Basically, JPA is the real DAO here. Previously, when JPA didn't exist, everyone homegrew DAO interfaces so that the service methods can keep using them even when the underlying implementation ("plain old" JDBC, or "good old" Hibernate, etc) changes. The real task of a service method is transparently managing transactions. This isn't the responsibility of the DAO.
See also:
I found JPA, or alike, don't encourage DAO pattern
DAO and JDBC relation?
When is it necessary or convenient to use Spring or EJB3 or all of them together?
And the controller feels like it's doing some of the job of the service.
I can imagine that it does that in this relatively simple setup. However, the controller is in fact part of the frontend not the backend. The service is part of the backend which should be designed in such way that it's reusable across all different frontends, such as JSF, JAX-RS, "plain" JSP+Servlet, even Swing, etc. Moreover, the frontend-specific controller (also called "backing bean" or "presenter") allows you to deal in a frontend-specific way with success and/or exceptional outcomes, such as in JSF's case displaying a faces message in case of an exception thrown from a service.
See also:
JSF Service Layer
What components are MVC in JSF MVC framework?
All in all, the correct approach would be like below:
<h:dataTable value="#{userBacking.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.name}</h:column>
</h:dataTable>
#Named
#RequestScoped // Use #ViewScoped once you bring in ajax (e.g. CRUD)
public class UserBacking {
private List<User> users;
#EJB
private UserService userService;
#PostConstruct
public void init() {
users = userService.listAll();
}
public List<User> getUsers() {
return users;
}
}
#Stateless
public class UserService {
#PersistenceContext
private EntityManager em;
public List<User> listAll() {
return em.createQuery("SELECT u FROM User u", User.class).getResultList();
}
}
You can find here a real world kickoff project here utilizing the canonical Java EE / JSF / CDI / EJB / JPA practices: Java EE kickoff app.
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
Filter do not initialize EntityManager
javax.persistence.TransactionRequiredException in small facelet application
It is a DAO, well actually a repository but don't worry about that difference too much, as it is accessing the database using the persistence context.
You should create a Service class, that wraps that method and is where the transactions are invoked.
Sometimes the service classes feel unnecessary, but when you have a service method that calls many DAO methods, their use is more warranted.
I normally end up just creating the service, even if it does feel unnecessary, to ensure the patterns stay the same and the DAO is never injected directly.
This adds an extra layer of abstraction making future refactoring more flexible.

what is a jaxb provider, jaxb handler, and contextResolvers?

1) What is a JaxB provider, and is it the same as a ContextResolver?
2) What is a jaxb handler?
I'm very lost in these terminologies. Please reply in simple to understand words.
Here it is from the book:
JAXB JAX-RS Handlers
The JAX-RS specification requires implementations to automatically support the marshalling and unmarshalling of classes that are annotated with #XmlRootElement or #XmlType as well as objects wrapped inside javax.xml.bind.JAXBElement instances. Here’s an example that interacts using the Customer class defined earlier:
#Path("/customers")
public class CustomerResource {
#GET
#Path("{id}")
#Produces("application/xml")
public Customer getCustomer(#PathParam("id") int id) {
Customer cust = findCustomer(id);
return cust;
}
#POST
#Consumes("application/xml")
public void createCustomer(Customer cust) {
...
}
}
As you can see, once you’ve applied JAXB annotations to your Java classes, it is very easy to exchange XML documents between your client and web services. The built-in JAXB handlers will handle any JAXB-annotated class for the application/xml, text/xml, or application/*+xml media types. By default, they will also manage the creation and initialization of JAXBContext instances. Because the creation of JAXBContext instances can be expensive, JAX-RS implementations usually cache them after they are first initialized.
Managing your own JAXBContexts with ContextResolvers
If you are already familiar with JAXB, you’ll know that many times you need to configure your JAXBContext instances a certain way to get the output you desire. The JAX-RS built-in JAXB provider allows you to plug in your own JAXBContext instances. The way it works is that you have to implement a factory-like interface called javax.ws.rs.ext.ContextResolver to override the default JAXBContext creation:
public interface ContextResolver<T> {
T getContext(Class<?> type);
}
ContextResolvers are pluggable factories that create objects of a specific type, for a certain Java type, and for a specific media type. To plug in your own JAXBContext, you will have to implement this interface. Here’s an example of creating a specific JAXBContext for our Customer class:
#Provider
#Produces("application/xml")
public class CustomerResolver
implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public CustomerResolver() {
this.ctx = ...; // initialize it the way you want
}
public JAXBContext getContext(Class<?> type) {
if (type.equals(Customer.class)) {
return ctx;
} else {
return null;
}
}
}
JAXB Provider
A JAXB provider is an implementation of the Java Architecture for XML Binding (JSR-222) specification. This specification was created through the Java Community Process. It was originally lead by Sun Microsystems, but is now lead by Oracle. The expert group had members from several object-to-XML technologies (XMLBeans, EMF, TopLink OX, etc) as well as several individuals. A JAXB implementation is required to pass the Test Compatibility Kit (TCK). Below are links to a couple of JAXB providers:
https://jaxb.java.net/
http://www.eclipse.org/eclipselink/moxy.php
ContextResolver
JAXB is the default object-to-XML provider in JAX-RS. By default it will create a JAXBContext based on the parameter/return type of the JAX-RS annotated method (i.e. annotated with #GET). Then it will pull in all referenced classes to produce metadata as well. Sometimes this doesn't produce all the required metadata and you need to provide the JAXBContext yourself. This can be done with a ContextResolver.
JAXB Handler
I'm not familiar with this term.
JAXB is the acronym for "Java Architecture for XML Binding", a specification defining ways to convert between XML documents and Java object trees, originally created by Sun Microsystems. The valid spec, version 2.0, was completed in 2006.
An implementation according to the JAXB specification is a JAXB provider.
The specification contains some hints, what a plausible implementation might contain. For instance: "The JAXBContext class is the entry point for a Java application into the
JAXB framework." It maintains information about the classes to expect during (un)marshalling. It is created either from one or more packages or from a list of classes. (The process of context resolution may follow hints in the annotation.)
The term "JAXB handler" (as it is used in the quoted text) refers to the code associated with a JAXBContext class that investigates a Java class, introspecting fields and methods and annotations, thus creating a database of all information contained within the Java code.

osgi dependency injection between services

I just started playing around with OSGi services and have the following situation. I have a project which contains 2 services. Service A requires Service B, so I tried to inject the dependent service using
#Inject
private ServiceB svc;
but the framework wont inject. If I setup the following two methods in Service A
and set these methods as "bind / undbind" in my OSGi componentA.xml the framework calls
these methods and I can use Service B in Service A.
public synchronized void bind(IServiceB service)
{
this.svc = service;
}
public synchronized void unbind(IServiceB service)
{
if (this.svc == service)
{
this.svc = null;
}
}
The question is, why does it not work with #Inject ? Sorry if this is a stupid question, I'm quite new to this whole topic. Many thanks in advance!
It looks like you are using Declarative Services, which does not support field injection or the JSR-330 annotations. Field injection has limited utility in OSGi, where services may be injected or "un-injected" at any time. Method injection is more generally useful because it gives you an opportunity to do something when this happens.
However I do urge you to use the annotations for Declarative Services. This will save you from having to write the component.xml by hand.

SessionScoped getting different instances

I'm getting different instances of a #SessionScoped bean for two calls to the same user session. What can lead to this?
A bean annotated #SessionScoped is injected into a servlet, and a RESTEasy JAX-RS web service endpoint. A user logs in using HTTPS with a certificate. First call goes to the RESTEasy endpoint. The next call from the browser goes to the servlet. I'd expect the same bean instance in both calls, but they are different. ... Any ideas?
Using JBoss 7.0.1
bean:
#Stateful
#SessionScoped
public class MyBean implements Serializable { ... }
REST endpoint:
#Path("/one")
public class MyService extends JAXRSPlugin {
#Inject MyBean myBean;
...
}
Servlet:
#WebServlet(urlPatterns = "/two", asyncSupported = true)
public class MyServlet extends HttpServlet {
#Inject MyBean myBean;
...
}
Turns out the REST service methods are not really supposed to have an HttpSession to share state. REST services are supposed to be stateless. They are given #SessionScoped beans as if they were #RequestScoped by design.
It's not what I want for this case, but maybe I should just not use REST for these calls. Mainly I just wanted the handy mapping of URL paths to methods in my REST service class. Servlets don't have path-to-method-mapping like that, as far as I know.
Basically I see 3 options: (1) make of find a dispatching mechanism to use in one Servlet, (2) use multiple Servlets, or (3) mis-use the REST by abusing the #Context HttpServletRequest to get to the HttpSession. I don't like abusing APIs, so option 3 is out. CDI might make option 2 cool, but option 1 is probably more common (and so might be easier to maintain by others).

Using an EJB inside a JAX-RS resource class in RestEasy?

I would like to have the following kind of resource class work when deployed under RestEasy in JBoss 6:
#Path("Something")
public class Foo {
#EJB
private SomeService service
#GET
public Object frobnicate() {
assert service != null;
// JBoss blows up here
return result;
}
}
Two questions:
It is a limitation of RestEasy, not of the Java EE specification, right, that RestEasy can't inject anything annotated with #EJB?
What have people done to work around this limitation?
My developers are about to surge forward with hard-coded JNDI lookups (e.g. context.lookup(someHardCodedNameHere)) because no one can find a workaround to this specification violation at the present time. I really want to avoid this.
Lastly, I've looked at using CDI, but the story here isn't much better as RestEasy and CDI still aren't talking to each other.
Thanks in advance for any pointers.
The JBoss guys tell me this is being worked on on the trunk. So as of JBoss 6 milestone 3 this is impossible.