Jersey Guice Accessing Post Parameters - scala

I have a Jersey client that is hooked up using Guice. Really hooked up :)
The resources are also created using Guice.
Something like:
#Inject
class TestResource {
#Inject DataFatcher fetcher,
...
...
}
Now, DataFetcher object is created using Guice and has deep nested guice-created objects using composition. Now, some of these object need access to parameters passed over using POST.
I have a HttpServletModule that does that for me. I I thought that does the right work.
HttpServletModule.java
Map<String, String[]> providerRequestParametersMap(HttpServletRequest reuquest) {
request.getParametersMap()
}
Now, unfortunately, It looks like Jersey, has already intercepter the request and removed the POST parameters from the request parameters Map. So, this Map of mine is empty.
How, can I get access to the POST Parameters in Guice ? I do not want to Inject the Form of MultivaledMap in the Resource directly, since that will need to be passed down all the way from the Resource which will mess up my design.
Any tips greatly appreciated. I can think of creating a Filter that intercepts the HttpServletRequest before the Jersey filters kicks in. Hoping that there is a better,easier solution :).

The easiest solution is probably a servlet Filter that does what you suggest: intercepting the HttpServletRequest before it's handled by Jersey and setting data in a request-scoped object.
If you're using Guice Servlet, filtering is at least a few keystrokes less setup than it is in web.xml.
If you'd prefer a Jersey-only solution, you could use a ContainerRequestFilter. This gives you access to ContainerRequest, which in turn provides you with a Form (a javax.ws.rs.core.MultivaluedMap).

Related

Multiple selectors using Sling Servlets

Short version: How do I force the most matching on a servlet based on multiple selectors using Felix annotations for sling servlets?
I have a few servlets defined in an OSGI bundle. I'm using the org.apache.felix.scr.annotations.sling.SlingServlet annotations.
#SlingServlet(
methods={GET},
selectors {"v1"}
...
)
public class MyServlet extends SlingAllMethodsServlet {}
...
#SlingServlet(
methods={GET},
selectors {"v1","special"}
...
)
public class MySpecialServlet extends MyServlet {}
My problem is that I can not find a way to force MySpecialServlet to only handle requests when both selectors are present.
GET http://localhost/my/resource.v1.special.json
Sometimes it will handle requests for only the v1 selector.
GET http://localhost/my/resource.v1.json
It seems that after using posting a new jar through the felix webconsole, if I request the double selector resource.v1.special.json before any other resource, then MySpecialServlet will also continue to handle v1 only requests.
Is there a way I can force the more general servlet to handle the more general list of selectors using the current annotations? Am I missing some part annotation? I believe that this system might be using an older annotation. Perhaps it is worth migrating? I'm trying not to be too intrusive for this small task that I've been asked to do.
Bear with me if I've conflated parts of these technologies. I've just walked up to this problem and I'm still sorting it out. Please correct any misalignment of terms.
Register your MySpecialServlet by v1.special, like selectors = {"v1.special"}.
According to the documentation:
... The selectors must be configured as they would be specified in the URL that is as a list of dot-separated strings such as print.a4 ...
I understand that when registering the servlet by a list of selectors, Sling treats them individually (as within OR condition). So, in the case of registering your special servlet by selectors = {"v1","special"}, the doGet method will be called if you request:
http://localhost/my/resource.v1.special.json or
http://localhost/my/resource.special.json or
http://localhost/my/resource.v1.json

How correctly implement a RESTful WS architecture using Spring MVC\Boot?

I am not so into RESTful web service and I have the following doubt about how to correctly implement RESTful style in my servics working on a Spring Boot application (Spring MVC is the same thing).
So basically I have some controller class like this:
#RestController
#RequestMapping("/RoomMedia")
public class RoomMediaController {
private static final Logger log = LoggerFactory.getLogger(RoomMediaController.class);
#Autowired
private RoomMediaService roomMediaService;
public RoomMediaController() {
log.debug("RoomMediaController init");
}
#RequestMapping(value = "getAllImagesByRoomId",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<byte[]>> getAllImagesByRoomId(Long roomId) throws DataAccessException {
log.debug("getAllImagesByRoomId START");
List<byte[]> result = roomMediaService.getRoomImageListById(roomId);
log.debug(result.toString());
log.debug("getAllImagesByRoomId END");
return ResponseEntity.ok(result);
}
}
I think that, also if the base idea is RESTful like, it can't be considered a true RESTful WS.
I think that the main problem is related to the endpoint: the getAllImagesByRoomId() method handle HTTP GET request toward URL like this: /RoomMedia/getAllImagesByRoomId?roomId=7
From what I have understand reading some tutorial this is not RESTful style because I have to access to a resource without passing parameter, I have to do someting like this:
/RoomMedia/Images/7
Is it my reasoning correct?
Moreover I think that the previous method is pretty trivial also in the implementation: this method return the list of all the images associated to a room having id=7(it is an application related to hotels).
From what I have understand also its logic is againts RESTful principles.
Is it better organize in the following way?
Doing a GET request like this:
/RoomMedia/7/Images/: I have to obtain the list of all the images associated to the room having id=7 as URI (or maybe is better handle a path like /7/RoomMedia/Images/ ?).
/RoomMedia/7/Images/1 I obtain the image with the id=1 associated to the room having id=7.
Are al these reasoning correct or am I missing something?
your assumtions are correct. Which of the mapping that you suggest, is deppending totaly on how your model is. Martin Fowler has a nice article about the Richardson Maturity Model which is sum up as:
Level 1 tackles the question of handling complexity by using divide and conquer, breaking a large service endpoint down into multiple resources.
Level 2 introduces a standard set of verbs so that we handle similar situations in the same way, removing unnecessary variation.
Level 3 introduces discoverability, providing a way of making a protocol more self-documenting.
For your project you could use jhipster because its offer you the best of spring with angular under a REST-ful design.
URLs must not contain a verb. The verb is provided by the method, in your case - surprise, surprise - GET.
ByRoomId is pointless as well, because that's what ?roomId= says.
That leaves AllImages, where All is superfluous.
Which results in the URL /RoomMedia/Images?roomId=7. What's unclear is the relationship between RoomMedia and Images, if there is any. If RoomMedia refers to a room, then your suggestion /RoomMedia/7/Images/ would be correct.
/RoomMedia/7/Images/1 is questionable. It should rather be /Images/1. It's irrelevant in which room the image with the id 1 is in.
When you design a REST API, then the first thing to do is to think about all resources you want to expose and their relationships. After that the URLs will reveal themselves automatically, so to speak.

No event context active - RESTeasy, Seam

I'm trying to add a RESTful web service with RESTeasy to our application running on JBoss 7.x, using Seam2.
I wanted to use as little Seam as possible, but I need it for Dependancy Injection.
My REST endpoints are as follows:
#Name("myEndpoint")
#Stateless
#Path("/path")
#Produces(MediaType.APPLICATION_JSON+"; charset=UTF-8")
public class MyEndpoint {
#In private FooService fooService;
#GET
#Path("/foo/{bar}")
public Response foobar(#CookieParam("sessionId") String sessionId,
#PathParam("bar") String bar)
{ ... }
}
I'm using a class extending Application. There is no XML config.
I can use the web service methods and they work, but I always get an IllegalStateException:
Exception processing transaction Synchronization after completion: java.lang.IllegalStateException: No event context active
Complete StackTrace
I did try everything in the documentation, but I can't get it away. If I leave out the #Stateless annotation, I don't get any Injection done. Adding #Scope doesn't do jack. Accessing the service via seam/resource/ doesn't even work (even without the Application class with #ApplicationPath).
It goes away if I don't use Dep. Injection, but instead add to each and every method
fooService = Component.getInstance("fooService");
Lifecycle.beginCall();
...
Lifecycle.endCall();
which isn't really a good solution. Nah, doesn't work either...
I have resolved the issue. For some reason (still not sure why, maybe because I tried to use Annotations and code exclusivly and no XML config), my REST service was availiable under a "non-standard" URL.
Usually it'd be something like "/seam/resources/rest".
Anyway, if you have a "custom" path, Seam doesn't know it should inject a context. You need to add <web:context-filter url-pattern="something" /> to your component.xml.
Specifically we already had this tag, but with the attribute regex-url-pattern and I extended it to match the REST URL.

Implementing Hypermedia in RESTful JAX-RS Apache CXF

I am working in a RESTful application developed in Apache CXF and I would like to introduce hypermedia functionality to it.
Most of our jaxrs:serviceBeans follow this template:
#GET
#Path("/{exampleId}")
public ExampleJSON get(#PathParam("exampleId") Integer exampleId) {
ExampleJSON example;
// Load data from repository here...
// Add link to self.
String href = javax.ws.rs.core.Link.fromResource(ExampleService.class).build().getUri().toString();
// HypermediaLink is a custom object to hold a "href" and "rel" strings
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + example.getId());
linkToSelf.setRel("self");
// Inherited method, just adds a HypermediaLink to a collection in the parent class
example.addHypermediaLink(linkToSelf);
// Return JSON compatible object, JACKSON will serialize it nicely.
return example;
}
This is the basic concept. Keep in mind that I simplified this code for explanation purposes; so, it can be easily understood.
This code works fine; but I am wondering if there is a better way to do this with Apache CXF. I have some ideas for how to enhancing it; however, it will require some custom annotations.
I see some examples using Jersey, but I would like to stick with Apache CXF.
Any help would be appreciated.
Thanks
I would leverage some features of JAX-RS and / or Jackson to implement the link adding under the hood at the serialization level. So you wouldn't need to have a specific field for the link within the bean itself.
You could implement a custom MessageBodyWriter to generate a different JSON payload (for example) for your POJOs than the default. So you could dynamically add the link.
See this answer for more details: How to write an XML MessageBodyWriter provider with jersey.
If you use Jackson for the serialization, you could implement a custom serializer. Note that this is generic and will work for all supported format of Jackson.
Below is a sample code:
public class LinkBeanSerializer extends JsonSerializer<SomeBean> {
#Override
public void serialize(SomeBean bean, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
// Fields
jgen.writeNumberField("id", bean.getId());
// Things could be generic using reflection
// Link
String href = javax.ws.rs.core.Link.fromResource(SomeBean.class).build().getUri().toString();
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + bean.getId());
linkToSelf.setRel("self");
jgen.writeObjectField("hypermediaLink", linkToSelf);
jgen.writeEndObject();
}
}
Note that we could make this serializer more generic I think (something like extends JsonSerializer<Object>)
See this answer for more details: Processing JSON response using JAX-RS (how to register the custom serializer within JAX-RS, ...).
Perhaps implementing a WriterInterceptor could solve your problem but there is impact on the beans since you need to have field hypermediaLink. The interceptor could be responsible of filling the field.
See this answer for more details: Jersey Update Entity Property MessageBodyWriter.
IMO the more convenient solution is the second one. It's transparent and support all the formats supported by Jackson.
Hope it helps you,
Thierry

Saving List<EntityProxy> in GWT RequestFactory

I want to save a list of entity objects in RequestFactory. Most of the time, i can find
RequestContext with Save(EntityProxy) alone and not with Save(List of EntitProxy).
Is it possible to do in GWT ?
In your RequestContext, add a method like
Request<Void> save(List<MyEntityProxy> proxies);
and have that map to a method like
public void save(List<MyEntity> entities)...
in your service class.
This may need to be static, depending on how you are using locators, and what kind of Request you are using. If this isn't working, can you post the full RequestContext (including annotations) and the error that occurs? It might give a hint as to why it isn't working correctly.