Is there a way to read the entity as jax-rs client? - web-services

I just made a jax-rs service and I'm trying to convert the String I get from the service to entities. While with jax-rs everything is done automatically on the server side I assume there is a possibility to do it on the client side as well but I'm not finding it.
public class MyClient {
public static void main(String[] args) {
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://localhost:8080/restapp/api/paints/1");
Response response = target.request().get();
Paint values = response.readEntity(Paint.class);
response.close();
}
}
this give an e:
Exception in thread "main" javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/json and type class client.Paint
(It works with String).

You need to add a JSON provider. For RESTeasy, you can see this link and select your version, and add the dependency.
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>${resteasy3.version}</version>
</dependency>

hi you can write ReastEasy or Jersy Client to get Json from your Service.
how to write client you can follow :http://entityclass.in/rest/jerseyClientGetXml.htm

Related

Preventing a WCF client from issuing too many requests

I am writing an application where the Client issues commands to a web service (CQRS)
The client is written in C#
The client uses a WCF Proxy to send the messages
The client uses the async pattern to call the web service
The client can issue multiple requests at once.
My problem is that sometimes the client simply issues too many requests and the service starts returning that it is too busy.
Here is an example. I am registering orders and they can be from a handful up to a few 1000s.
var taskList = Orders.Select(order => _cmdSvc.ExecuteAsync(order))
.ToList();
await Task.WhenAll(taskList);
Basically, I call ExecuteAsync for every order and get a Task back. Then I just await for them all to complete.
I don't really want to fix this server-side because no matter how much I tune it, the client could still kill it by sending for example 10,000 requests.
So my question is. Can I configure the WCF Client in any way so that it simply takes all the requests and sends the maximum of say 20, once one completes it automatically dispatches the next, etc? Or is the Task I get back linked to the actual HTTP request and can therefore not return until the request has actually been dispatched?
If this is the case and WCF Client simply cannot do this form me, I have the idea of decorating the WCF Client with a class that queues commands, returns a Task (using TaskCompletionSource) and then makes sure that there are no more than say 20 requests active at a time. I know this will work but I would like to ask if anyone knows of a library or a class that does something like this?
This is kind of like Throttling but I don't want to do exactly that because I don't want to limit how many requests I can send in a given period of time but rather how many active requests can exist at any given time.
Based on #PanagiotisKanavos suggjestion, here is how I solved this.
RequestLimitCommandService acts as a decorator for the actual service which is passed in to the constructor as innerSvc. Once someone calls ExecuteAsync a completion source is created which along with the command is posted to the ActonBlock, the caller then gets back the a Task from the completion source.
The ActionBlock will then call the processing method. This method sends the command to the web service. Depending on what happens, this method will use the completion source to either notify the original sender that a command was processed successfully or attach the exception that occurred to the source.
public class RequestLimitCommandService : IAsyncCommandService
{
private class ExecutionToken
{
public TaskCompletionSource<bool> Source { get; }
public ICommand Command { get; }
public ExecutionToken(TaskCompletionSource<bool> source, ICommand command)
{
Source = source;
Command = command;
}
}
private IAsyncCommandService _innerSrc;
private ActionBlock<ExecutionToken> _block;
public RequestLimitCommandService(IAsyncCommandService innerSvc, int maxDegreeOfParallelism)
{
_innerSrc = innerSvc;
var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism };
_block = new ActionBlock<ExecutionToken>(Execute, options);
}
public Task IAsyncCommandService.ExecuteAsync(ICommand command)
{
var source = new TaskCompletionSource<bool>();
var token = new ExecutionToken(source, command);
_block.Post(token);
return source.Task;
}
private async Task Execute(ExecutionToken token)
{
try
{
await _innerSrc.ExecuteAsync(token.Command);
token.Source.SetResult(true);
}
catch (Exception ex)
{
token.Source.SetException(ex);
}
}
}

Migrating a CXF client that uses "simple frontend" to JAX-WS

I have a web service client written with Apache CXF, that uses the simple frontend style. It can dynamically invoke a method on a remote web service, given its location and the interface implemented by the service.
public static void callWsMethod(Class<?> serviceInterface, String address, String methodName,...) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(serviceInterface);
factory.setAddress(address);
Object instance = factory.create();
... /*invoke method "methodName" on instance */
I want to migrate this code to a pure JAX-WS implementation. My code should look something like:
public static void callWsMethod(Class<?> serviceInterface, String address, String methodName,...) {
URL wsdlLocation = new URL(address + "?wsdl");
QName serviceName = new QName( .... , ....); //??? what goes here
Service service = Service.create(wsdlLocation, serviceName);
Object instance = service.getPort(serviceInterface);
... /*invoke method "methodName" on instance */
I suspect that this is possible because the CXF doc cited above says:
In a 'simple' case, very nearly identical things happen in the Simple front end as in JAX-WS.
My first problem is the QName constructor:
QName(java.lang.String namespaceURI, java.lang.String localPart)
how does CXF figure out the right namespaceURI and localPart to invoke the ws?
Do you have a WSDL?
namespaceUri = /wsdl:definitions/#targetNamespace
localPort = /wsdl:definitions/wsdl:service/#name
If you have a WSDL. Why not simply generate the SEI classes using wsimport? You'll see the generated automatically contains the right QName.

JAX-WS web service with Source return type on Websphere

I am migrating an old JAX-WS 2.1 web service from JBoss 4 to Websphere 7. Most of the #WebMethod components all look like this:
#WebMethod
public Source someMethod(){
Source source = null;
try{
source = ServiceActions.someMethodWorker();
}
catch( Throwable throwable ){
source = ServiceActions.handleThrowable("Error occured in method someMethod", throwable );
}
return source;
}
ServiceActions.someMethodWorker() usually goes off and fetches that data populates a JAXB structure, marshalls into XML and returns a StreamSource of the XML like this:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JAXBContext jc = JAXBContext.newInstance();
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(someJaxBObjectHierarchy, byteArrayOutputStream);
return new StreamSource(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
This web service runs just fine on JBoss 4 (with the Jax-WS and JaxB libraries) and GlassFish 3.1, but Websphere 7 keeps giving me the following error any time I use a client against the web service:
javax.xml.ws.soap.SOAPFaultException: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class javax.xml.transform.stream.StreamSource nor any of its super class is known to this context.]
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:107)
At first look this seems to be the JAXB type binding problem; however, I've added #XmlSeeAlso(StreamSource.class) everywhere, and I still get the error.
Would someone know why this is failing on WebSphere 7?
Thanks!
Edit/Solution: The solution is to use byte[] return type instead of Source
GlassFish and JBoss were doing something extra compared to the JAX-WS specification which led me to believe that Source return type was OK.
Instead of my methods returning new StreamSource(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) they now just return byteArrayOutputStream.toByteArray()
javax.xml.transform.Source is not a valid return type for a normal JAX-WS service endpoint interface (SEI). If you want to do that (and be compliant with JAX-WS) you need to use a service that is implemented as a javax.xml.ws.Provider (see the corresponding docs). If JBoss or GlassFish support Source as a parameter or return type in a normal SEI, then that's a proprietary extension.

Multiple content type support using JAX-RS

The goal is to create a rest-full web service using JAX-RS that will selectively return the result either in json or xml format, depending on the user request. For example, if the user issues a GET request in the following fashion the results will be returned in json format:
http://api.myurl.com/order/1234.json
Similarly, if the user issues a get in the following request, the results will be returned in xml format:
http://api.myurl.com/order/123.xml
I don't want to use request parameters to do this (i.e. http://api.myurl.com/order/123?format=json). Using the .json or .xml post-fix seems more intuitive to me.
What would be the best strategy for doing this using the JAX-RS api?
One way would be to use #Path annotations more thoroughly:
#GET
#Path("/order/{id}.xml")
#Produces("application/xml")
public Order getOrderAsXML(#PathParam("id") int id) {
return realGetOrder(id);
}
#GET
#Path("/order/{id}.json")
#Produces("application/json")
public Order getOrderAsJSON(#PathParam("id") int id) {
return realGetOrder(id);
}
private Order realGetOrder(int id) {
// ...
}
However I'd be inclined to have a single method serving up both and let the client and supporting JAX-RS framework use content negotiation to decide the serialization method.

How to return HTTPResponse from ASMX web service to consumer web page

I am working on an ASMX web service; trying to create a method that will download a document from a server and show the document in the browser (the calling .aspx web page). My service builds without error but I get the following error when I try to "Add Web Reference" in my Proxy class project:
System.Web.HttpResponse cannot be serialized because it does not have a parameterless constructor.
Here is a snippet of the code in .ASMX file:
public class FileService : System.Web.Services.WebService
{
[WebMethod]
public void DownloadDocument(string URI, HttpResponse httpResponse)
{
int DownloadChunkSize = (int)Properties.Settings.Default.DownloadChunkSize;
// some more code here....
using (httpResponse.OutputStream)
{
// more code here...
}
}
}
I see I am confused about how to send back an HttpResponse from a web service to a requesting web page. Could someone please give me a tip on how to do this? Thanks.
You should look into web handlers (.ashx). They are perfect for what you are trying to achieve.
For example:
public class Download : IHttpHandler, IRequiresSessionState {
public void ProcessRequest(HttpContext context) {
var pdfBytes = /* load the file here */
context.Response.ContentType = #"Application/pdf";
context.Response.BinaryWrite(pdfBytes);
context.Response.End();
}
}
UPDATE:
An ashx handler is actually a replacement to aspx. Basically, it has no UI but still processes get / post requests just like an aspx page does. The point is to reduce the overhead generated by running a regular aspx page when all you need to do is return some simple content (like a file...) or perform a quick action.
The IRequiresSessionState interface allows you to use the SESSION object like any other page in your site can. If you don't need that, then leave it off.
This site has an interesting walk through on how to create one. Ignore Step 4 as you probably don't care about that.
Assuming that you have a regular page (aspx) that has a link to your document: The link in the aspx file would actually point directly to your ashx handler. for example:
Click Here
Then the code in the ProcessRequest method of the ashx handler would do whatever calls it needed (like talk to your DLL) to locate the document then stream it back to the browser through the context.Response.BinaryWrite method call.
That is not how standard ASMX web services work. If you want to make your own handler, or even use an ASPX page to deliver the doc, you are fine, but the standard ASMX web service method of doing this is to actually return the bits of the document as an encoded blob.
If you want to roll your own, consider this article:
http://msdn.microsoft.com/en-us/magazine/cc163879.aspx
The web smethod (from asmx) returns an object, which can be serialized.
You need to create your method like:
[WbeMethod]
public byte[] DownloadDocument(string URI)
Or if the content is some text - return string.