JAX-RS: Resolve URI of Linked Resources on the Server - java

is there a standard way (JAX-RS) to resolve REST URIs to resources on the server side? As I understand the common practices, it's best to provide a full URI as an identifier for resources. If I want to allow somebody to POST/PUT a document like this to create/change a product:
<product>
[...]
<categories>
<category>http://.../rest/categories/12</category>
<category>http://.../rest/categories/35</category>
</categories>
</product>
As you can see, the references to the categories are their resource URIs. On the server side I now have to resolve these URIs to the corresponding resources. The simplest approach would be to create a client for the service on the server itself and do a standard GET request on these URIs. But I feel like this shouldn't be necessary.
Is there a standard way to do this? Is there a CXF way to do this? Is it better to always provide an additional id as well?
Thanks.
Dominik

I think you are looking for -
http://jersey.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/core/ResourceContext.html
It is not from CXF or JAX-RS but from Jersey. I used it to parse documents just as in your example.
Inject it using #Context into your resource to use it.

Related

Java Californium CoAP Server

I am using Californium Library for my CoAP Server.
I have no difficulties using it.
However, I was wondering if there is a way to set my resource as "root resource".
It seems that some sites have no "suburl" on their server URL. (for ex. coap://192.168.0.1:8080/ )
ATM, since I don't know how to set my resource as "root resource", my url seems like this "coap://192.168.0.1:8080/myResource/"
Is there any way to bind my resource to root context?
Thank you
No, if you use the CoapServer class.
this.root is a private final there and there is no option to change it:
org.eclipse.californium.core.CoapServer source at github
Theoretically, you may try to implement the org.eclipse.californium.core.server.ServerInterface using the CoapServer source of appropriate version.
Though, this approach is bad and fragile.
However, exposing your resources as restful resources which have their own names is assumed by the CoAP Specification itself as it relies on REST:
RFC 7252 - The Constrained Application Protocol (CoAP). Section 1

Restlet Client using JAX-RS annotated resources

I am writing a restlet client that will invoke some Resteasy coded rest services (cannot change the server code, hence cannot use the Restlet way of annotating resources).
Resource Interface is using JAX-RS annotations and have more than one #POST method (one of the biggest problems of Restlet when dealing with this).
I was trying to do my implementaion this way:
IAppLoginResource resource = JaxRsClientResource.createJaxRsClient("http://localhost:9090/rest", IAppLoginResource.class);
final GetLoginAppInfoResponse response = resource.getLoginAppInfo( getLoginAppInfoRequest );
The problem is that the request by default is GET, I didn't find a way to specify the request method like when using ClientResource (which I can't use because I need to deal with JaxbRepresentation and Jaxb problems).
Any sample/snippet of code that implement a Restlet client using JAX-RS annotated resources?
Any ideas?
Thanks,
I've entered an issue for this topic:
https://github.com/restlet/restlet-framework-java/issues/1081
I've tested a sample application based on your code, and it works properly using the current 2.3 branch (future 2.3.3). I wonder if the fix for this issue https://github.com/restlet/restlet-framework-java/issues/1072 helps.
Regarding the documentation, I 'll complete the current page (http://restlet.com/technical-resources/restlet-framework/guide/2.3/extensions/jaxrs), cf this issue: https://github.com/restlet/restlet-framework-java/issues/1084.
You can also have a look at the org.restlet.test project, especially in this package https://github.com/restlet/restlet-framework-java/tree/2.3/modules/org.restlet.test/src/org/restlet/test/ext/jaxrs.

How to create a web service proxy? Can we generate #Endpoints?

I'm working on a web-service-proxy with auditing (later on with caching = creating own responses) and I need to generate #Endpoints (such that will just forward i.e. call a remote web service or dummy atleast). Marshaling/unmarshaling seems neccessary for the proxy will add "something" to the request...
We are to use spring-ws and JAXB. Got all XSDs and static WSDLs of the proxied web service.
Any hints around? Anyone doing something similar? How are you doing it?
Is there a simple way how to achieve this using spring or spring-integration?
Thanks in advance..
This should be possible using both Spring WS and Spring Integration:
With Spring WS, you can create a proxy class for your remote WS, wrapping around a org.springframework.ws.client.core.WebServiceTemplate to talk to the WS - which has API's to take care of marshalling the request to xml and unmarshalling the response.
With Spring Integration, you can use an outbound Webservices gateway , but you will need to front it with a messaging gateway, which will act as your proxy, along these lines:
<int:gateway id="wsproxy" service-interface="..ProxyInterface" default-request-channel="requestChannel" default-reply-channel="replyChannel"/>
<int-ws:outbound-gateway id="wsGateway" request-channel="requestChannel" uri="http://serviceURL" marshaller="someMarshaller" unmarshaller="someUnmarshaller"/>
However, I would recommend the first approach of using the WebserviceTemplate, as you do not have a very complex integration need here.
Today I can tell how we proceeded without spring-integration. We found two different ways how to generate #Endpoint class.
1) Using XSLT and Freemarker we generated the endpoint class source in pre-compile phase. XSLT transformation walked thru all WSDL files to create one summary file which was then used to generate the source.
2) Using Javassist we copied the template class, then generated methods regarding content of JAXB2Marshaller instance and finally instantiated object using FactoryBean, all at server start-up.
Problem here we met was set of XSD files written in form that caused the root objects were generated without #XmlRootAnnotation. Javassist version we had internally works with Java 1.4 (no generics) so we used global customization file for XJC and forced #XmlRootAnnotation on root objects.
Both solutions have their pros and cons but both are simpler then using ESB.

Accessing SOAP web service with incorrect wsdl

Background:
I need to consume an existing web service (SOAP over http) that has a couple of issues:
1) The wsdl on the server doesn't even resemble the web service as described in their documentation, which includes a completely different wsdl file
2) The wsdl file provided with their documentation seems to come close to describing the web service on the server, but when I generated java client code using cxf and used it to access the web service, cxf throws exceptions like the following
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://us-labs.companyxyz.com/", local:"searchResponse"). Expected elements are <{http://companyxyz.com/xyz-xml/2.0/}searchResponse>
... 33 more
I'm no SOAP expert, but assuming this means the namespaces in their response don't match those defined in the wsdl.
Since my application is written in java, I was able to connect and get a response using commons http client and a handcrafted SOAP request, so worst case I can fall back to that and parse the response to get what I need.
My questions:
Did I interpret the exception correctly?
If no: any suggestions on how I can debug this?
If yes: can anyone suggest better alternatives to handcrafting http requests and parsing xml by hand? (Getting correct wsdl is, unfortunately, not an option)
Thanks in advance.
Most likely. The response is using the namespace "http://us-labs.companyxyz.com/", but in the WSDL, the same element is declared with namespace "http://companyxyz.com/xyz-xml/2.0/".
I'm not familiar with CXF, but other SOAP frameworks usually offer some kind of logging capabilities. It would probably help you if the SOAP requests and responses are logged somewhere for more specific analysis.
Why is it not an option to get a correct WSDL? If you really are able to "handcraft" correct SOAP requests and expect to be able to "handparse" the responses, you should be able to write the WSDL yourself as well. Of course, the WSDL should be provided to you by the service operator, but if you mean that noone is able to provide you with a correct WSDL, I would consider writing it myself instead of creating and parsing the SOAP messages manually.
I think you interpreted the exception correctly - the namespace is different than expected.
It is also not really unexpected. it is a fact of life that vendor supplied wsdls are not always correct. We actually write our own WSDLs and XSDs for vendor applications for just that reason.
You can use your own WSDL even run-time. There are some SO questions on that, here and here.
You could also have a look here. I haven't tried it, but it could work.
We actually extend the generated service and create a port supplying a WSDL located on the classpath using the JaxWS Service constructor. That works fine for us.
We debug CXF by dumping the incoming and outgoing messages. There seem to be quite a lot of methods to do just that. We use either a proxy between de web service and our client, or recently a cxf.xml file somewhere. Using a -D flag we temprarily configure this.
-Dcxf.config.file=/home/me/cxf-debug.xml
and cxf-debug.xml contains something like:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
</beans>
http://cxf.apache.org/docs/debugging-and-logging.html
Both responses suggested the same basic approach, which turned out to be the correct one.
I fixed the provided wsdl to make it match the web service, and I was able to use cxf, which saved me a lot of hand coding.
The main problem with their wsdl was in fact a namespace issue. The essence of the problem was as follows: their wsdl defined two namespaces, both of which have a "searchResponse" element.
{http://us-labs.companyxyz.com/}searchResponse
was defined in the wsdl to contain 0 or more
{http://companyxyz.com/xyz-xml/2.0/}searchResponse
But in their response the nested searchResponse wasn't qualified by {http://companyxyz.com/xyz-xml/2.0/} so cxf interpreted it as a {http://us-labs.companyxyz.com/}searchResponse
I fixed it by introducing a new type.
Thanks to both responders.

Streaming Dynamic Files from Spring MVC

I've got a Spring Web MVC application (and also a BlazeDS application, though not as relevant) where files are dynamically generated based on certain client actions.
I'd like to just map a certain directory on the file system to Spring MVC (or the app server) url and let it serve the files in that directory (with streaming and standard last-modified header support). Ideally, the mapped directory would be configured via the spring config, since I already have support per-machine for setting that up.
So, how can I do this? The best I can find so far is to write a controller that reads the file manually and streams it byte-by-byte. However, that seems far less than ideal. Is support for something like this already baked into Spring MVC or the standard application server spec?
Thanks!
If your processing model supports it, why not cut the middleman of the filesystem out of the picture completely and just stream the files back through the response stream as they are generated? Take a look at the AbstractExcelView and AbstractPDFView classes of Spring MVC to see some examples of how this is done.
or the standard application server spec?
Yes, there is. As you didn't mention which one you're using, I'll give a Tomcat-targeted answer. All you basically need to do is to add a Context element for /path/to/your/resources in /conf/server.xml:
<Context docBase="/path/to/your/resources" path="/resources" />
This way they'll be accessible through http://example.com/resources/...
Ideal for this is using an lightweight proxying server in front of your appserver, like a nginx or lighthttpd. You can configure it for serving static content, without calling your app.
If directory and files so dynamic, you can prepare real path to file at your controller and give this filepath to the frontend server, using headers. For example for nginx it's a X-Accel-Redirect header. Read more about this (and follow links for other http servers) there

Categories

Resources