How to perform previous process on a RESTful WebService call? - java

im developing a WebApplication based on RESTful WebServices. I used the NetBeans "New File Manager" to automatically generate my "Entity Classes from database" and the "RESTful Web Services fom Entity Classes" so everything is fine and I get something like:
#Stateless
#Path("usuario")
public class UsuarioFacadeREST extends AbstractFacade<Usuario> {
#PersistenceContext(unitName = "TSERMEXeCommercePU")
private EntityManager em;
public UsuarioFacadeREST() {
super(Usuario.class);
}
#POST
#Override
#Consumes({"application/xml", "application/json"})
public void create(Usuario entity) {
super.create(entity);
}
#PUT
#Override
#Consumes({"application/xml", "application/json"})
public void edit(Usuario entity) {
super.edit(entity);
}
#DELETE
#Path("{id}")
public void remove(#PathParam("id") Integer id) {
super.remove(super.find(id));
}
#GET
#Path("{id}")
#Produces({"application/xml", "application/json"})
public Usuario find(#PathParam("id") Integer id) {
return super.find(id);
}
#GET
#Override
#Produces({"application/xml", "application/json"})
public List<Usuario> findAll() {
return super.findAll();
}
I have REST services for every entity on my DB. So everything is going good so far.
But I have a little problem, I need every service call to check if the user is loged in and if he has the permission to call that service, for example:
Im going to have an extra service on my UsuarioFacadeREST called logIn() that receive a user, password, and if is it correct, im going to add a "logedIn:true" parametter to his HTTPSession so i can always know if he has already loged in, something like:
#GET
#Path("login/{user}/{pass}")
#Produces({"application/xml"})
public String logIn(#PathParam("user") String user, #PathParam("pass") String pass, #Context HttpServletRequest request) {
Usuario userEntity;
if( (userEntity = getUserFromDB(user, pass)) != null ) {
HttpSession session = request.getSession();
session.setAttribute("logedIn", true);
session.setAttribute("priviledges", loadPrivilegdesList(userEntity));
return "<logedIn>true</logedIn>";
} else {
return "<logedIn>false</logedIn>";
}
}
So, once he has loged in, I load his priviledges list on his session.
These privilegdes are Strings like "VIEW_CUSTOMER_LIST", "ADD_CUSTOMER", "EDIT_CUSTOMER", "DELETE_CUSTOMER", "ADD_PRODUCT", "EDIT_PRODUCT", etc, etc.
What does this means? this means that on my CustomerFacadeREST service, for every REST service(every function call), i will nedd to check the user loggedIn status and his privilegdes list. By this way i will be able to know if i can offer the user this service or i have to deny it to him.
The problem is that i think is not a good practice to edit all the autogenerated RESTful Web Services to check in every function if the HttpSession has the attribute logedIn.
So, i wish to know if is there any way to have a pre-service-call function for all the RESTful web services that check, on every service call, befor call it, the logedIn attribute of the HttpSession. I mean, I want to lock all the webServices calls and redirect them to this function so it check the things that I need to be checked and then it call the original function called by the user.
Is there any way to solve this?
Thanks so much for reading. Please tell me if I am not clear enough.

Related

How to logout programmatically from magnolia cms

I'd like to create custom REST for logging out users. I created jax-rs based endpoint definition with one method /logout:
#Path("/test")
public class MyEndpoint<D extends EndpointDefinition> extends AbstractEndpoint<D> {
#Path("/logout")
#GET
#Produces(MediaType.APPLICATION_JSON)
public void logout() {
//how to logout user here?
}
}
What code should I put in place of //how to logout user here? to make it work?
You can inject the following component and trigger logout from it.
info.magnolia.context.UserContext
I created working solution based on info.magnolia.cms.security.LogoutFilter
#Path("/logout")
#GET
#Produces(MediaType.APPLICATION_JSON)
public void logout(#Context HttpServletRequest request) {
info.magnolia.context.Context ctx = MgnlContext.getInstance();
if (ctx instanceof UserContext) {
AuditLoggingUtil.log((UserContext) ctx);
((UserContext) ctx).logout();
}
if (request.getSession(false) != null) {
request.getSession().invalidate();
}
}

Java REST: #GET and #PUT at the same path?

I have currently trying to learn the basics of Java REST, using JAX-RS.
Within the UserService class (near bottom) of this example there is both an #GET AND #PUT method with the same #path annotation:
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_XML)
public List<User> getUsers() {
return userDao.getAllUsers();
}
and
#PUT
#Path("/users")
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String createUser(#FormParam("id") int id,
#FormParam("name") String name,
#FormParam("profession") String profession,
#Context HttpServletResponse servletResponse) throws IOException {
User user = new User(id, name, profession);
int result = userDao.addUser(user);
if(result == 1) {
return SUCCESS_RESULT;
}
return FAILURE_RESULT;
}
How does the Program know which method to invoke, considering that they are both point at the same #path ?
Resource classes have methods that are invoked when specific HTTP method requests are made, referred to as resource methods. In order to create Java methods that will be invoked with specific HTTP methods, a regular Java method must be implemented and annotated with one of the JAX-RS #HttpMethod annotated annotations (namely, #GET, #POST, #PUT, and #DELETE).
For more info take a look at this example1 and example2
JAX-RS evaluates the HTTP method of the request and then calls the appropriate Java method in UserService.

How to get resource object in RequestFilter in Jersey

As I understand, it's possible to get resource class and method using injected ResourceInfo, but I need to execute some method of my resource class in request filter, so I need to get this object.
Or maybe the whole idea of getting exact object is wrong in this case?
UPD:
Here is a description of the original problem:
For example I have resource that returns all users and it also can return a subresource for particular user:
#Path("users") public class UsersResource {
#GET List<User> getUsers() {...}
#Path("{id}") UserSubresource getById(PathParam("id") String id) {
return new UserSubresource(getUserById(id));
}
}
Here is UserSubresource:
public class UserSubresource {
User user;
#GET public User getUser() {return user;}
...
public boolean isAccessible() {
return user.isAccessibleByCurrentUser();
}
}
And I need to check access rights for getUser() method, I can't check permissions before I find out actual user.
I understand that I can add this check in getUser() method itself, but this situation is the same for some other entities in my application, so I want more common solution.

How to handle Backgrid.js cell edition requests

I am working with Backgrid these days.
Trying to edit a row value and to persist the database object, I end up with the following HTTP error:
NetworkError: 405 Method Not Allowed - http:// localhost:8084/fsrtool/api/roles/5
My web application driven by a Java Spring backend.
The Backgrid frontend is supposed to call the following method:
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
#Override
public Role getById(#PathParam("id") Long id) {
LOG.info("get a role with its ID");
Role r = rds.getById(id);
return r;
}
I know that my service class is working, because I am able to create new 'Roles' from the Backgrid table and thanks to the following method:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Override
public Response create(final Role r) {
return Response.status(Status.CREATED).entity(rds.getOrSave(r)).build();
}
Investigating the problem, I figured out that backgrid sent the request with PUT method.
I then tried several changes into my service class in order to handle this request, but I have not been able to find the good way of setting this up.
Would you know how Backgrid cells should be edited?
So, as the application I'm working on seems to be designed, I actually was not using the good library...
The way I need my service method to be:
#PUT
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}")
public Response update(final Role r, #PathParam("id") Long id) {
// do some processing... save to the db
}

How do I get the JAX-RS #Path of a different resource during a POST?

I have two REST classes for a simple web service (Jersey and GlassFish) that involves user resources - one to operate on all users (e.g., a factory for #POSTing) and another on individual users (e.g., #GET, #PUT, #DELETE). They are at:
#Stateless #Path("users") public class AllUsersResource {...}
#Stateless #Path("user") public class OneUserResource {...}
respectively. When POSTing to AllUsersResource I want to return the Location (via Response.created(uri).build()) of the new User, e.g.,
http://localhost:8080/.../user/152
My question is how to do this. AllUsersResource injects #Context UriInfo uriInfo, but that does not get me #Path info for OneUserResource, only that of the current call ("users"). The way I finally got it working was simply to use reflection, but I'm worried it is brittle and unclean:
OneUserResource.class.getAnnotation(Path.class).value();
Searching StackOverflow the only other things I found to try were the following, without success:
com.sun.jersey.api.core.ResourceContext
javax.ws.rs.core.UriInfo.getMatchedResources()
#javax.inject.Inject OneUserResource oneUserRes;
Any help would be terrific!
You can use UriBuilder.fromresource(), but this only works if the supplied Resource class is a root resource (this is clearly mentioned in the javadocs). I found a way to achieve this even if you are in a sub-resource class:
#POST
#Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
public Response createUser(final User user, #Context UriInfo uriInfo) {
// persist the user here
URI uri = uriInfo.getAbsolutePathBuilder().path(user.getId()).build();
return Response.created(uri).build();
}
I found a couple of javax.ws.rs.core.UriBuilder methods that did the trick, which I wanted to share in case others had this question. They are: UriBuilder.fromResource(OneUserResource.class) and javax.ws.rs.core.UriBuilder.path(Class). I used the latter in a one-shot call:
URI newUserUri = uriInfo.getBaseUriBuilder().path(OneUserResource.class).path("/" + user.getId()).build();
return Response.created(newUserUri).build();
With the strict REST concept you can make it as one root resource
#POST /users -> CREATE a single user
#GET /users -> READ all users
#PUT /users -> UPDATE (REPLACE) all users ##?
#DELETE /users -> DELETE all users ##?
#POST /users/{id} -> CREATE a single user's some other child; ##?
#GET /users/{id} -> READ a single user
#PUT /users/{id} -> UPDATE a single user
#DELETE /users/{id} -> DELETE a single user
#Path("/users")
#Stateless
public class UsersResouce {
// /users
#POST
#Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
public Response createUser(final User user) {
// persist the user here
return Response.created("/" + user.getId()).build();
}
// /users
#GET
#Produces({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
public Response readUsers() {
//return all users
}
// /users/{id}
#GET
#Path("/{user_id: \\d+}")
#Produces({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
public Response readUser(
#PathParam("user_id") final Long userId) {
final User persisted = userBean.find(userId);
if (persisted == null) {
return Response.status(Status.NOT_FOUND).build();
}
return Response.ok().entity(persisted).build();
}
// /users/{id}
#Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
#PUT
#Path("/{user_id: \\d+}")
public Response updateUser(
#PathParam("user_id") final Long userId,
final User mergeable) {
final User persisted = userBean.find(userId);
if (persisted == null) {
userBean.persist(mergeable);
} else {
persist.setName(mergeable.getName());
userBean.merge(persisted);
}
return Response.status(Status.NO_CONTENT).build();
}
// /users/{id}
#DELETE
#Path("/{user_id: \\d+}")
public Response deleteUser(
#PathParam("user_id") final Long userId) {
userBean.delete(userId);
return Response.status(Status.NO_CONTENT).build();
}
#EJB
private UserBean userBean;
}
As of JAX-RS 2.0, the most correct way (As far as I know) is to use the builder method like so:
String uri = uriInfo.getBaseUriBuilder()
.path(ODataV4Endpoint.class)
.path(ODataV4Endpoint.class, "serviceEndpointJSONCatalog")
.resolveTemplate("endpointId", endpointId).build().toString();
FYI, I need to call path twice in my case, once for the path annotation on the class, and the second time for the annotation on the method. I suspected the call to the method would do both, but it does not.
The Path annotation on the endpoint serviceEndpointJSONCatalog declared a parameter, like so: 'endpoint/{endpointId}', so the call to resolveTemplate was needed. Otherwise you would just call path(Class cl, String method).
In my case I created a builder and a symbolic way to reference the methods so the compiler / runtime could check them.

Categories