I am new to RESTful API client development. I have a got the sample client code to integrate to REST Server. Below is the the snap shoot of same.
public TsbPublishClient() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("publication");
}
public <T> T getJson(Class<T> responseType, String product, String version, String category) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("registry/{0}/{1}/{2}", new Object[]{product, version, category}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
public void close() {
client.close();
}
My question is how do i invoke the getJson() method from my main class. The return type is T and it accepts responseType parameter which is of type Class <T>
Thanks in Advance.
I'm a bit surprised that you want to use JAX-WS to access a RESTful API. In this technology, a web service operation invocation is represented by an XML-based protocol such as SOAP.
There are several technologies to do a call to a RESTful applications. Here are two of them:
Restlet - a lightweight and robust Java REST framework that tackles both client and server sides.
JAX-RS (JSR 311: JAX-RS: The Java API for RESTful Web Services) - a standardized API to both consume and produce RESTful applications. Restlet provides an implementation of this specification.
Following code describes a sample of client with Restlet:
ClientResource cr = new ClientResource("http://(...)/contacts");
MyDataBean bean = cr.get(MediaType.APPLICATION_JSON);
Following code describes a sample of client with JAX-RS:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://(...)")
.path("contacts");
MyDataBean bean = target
.request(MediaType.APPLICATION_JSON_TYPE)
.get(MyDataBean.class);
Both tools can leverage content (JSON, XML, YAML, ...) / POJO conversion with for example Jackson.
Hope it helps you,
Thierry
Related
Can someone tell me or give a ready-made CRUD example using WebFlux, RScoket and Spring (or SpringBoot)?
I studied the RSocket documentation, WebFlux, also wrote my simple examples, but I would like to see a real CRUD application using basic methods using RSocket.
I'll be very grateful.
Thanks.
I have maintained a Spring/RSocket sample project with 4 basic interaction modes of RSocket.
If you only require request/reply case for simple CRUD operations, check the request and response mode, and select a transport protocol, TCP or WebSocket.
To implement CRUD operations, just define 4 different routes for them, like define the RESTful APIs using URI, you have to have a good plan for the naming, but in RSocket there are no HTTP methods to help you to differentiate the same routes.
For example, in the server side, we can declare a #Controller to handling messages like this.
#Controller
class ProfileController {
#MessageMapping("fetch.profile.{name}")
public Mono<Profile> greet(#DestinationVariable String name) {
}
#MessageMapping("create.profile")
public Mono<Message> greet(#Payload CreateProfileRequest p) {
}
#MessageMapping("update.profile.{name}")
public Mono<Message> greet(#DestinationVariable String name, #Payload UpdateProfileRequest p) {
}
#MessageMapping("delete.profile.{name}")
public Mono<Message> greet(#DestinationVariable String name) {
}
}
In the client side, if it is a Spring Boot application, you can use RSocket RSocketRequester to interact with the server side like this.
//fetch a profile by name
requester.route("fetch.profile.hantsy").retrieveMono()
//create a new profile
requester.data(new CreateProfileRequest(...)).route("create.profile").retrieveMono()
//update the existing profile
requester.data(new UpdateProfileRequest(...)).route("update.profile.hantsy").retrieveMono()
//delete a profile
requester.route("delete.profile.hantsy").retrieveMono()
Of course, if you just build a service exposed by rsocket protocol, the client can be a rsocket-js project or other languages and frameworks, such as Angular, React or Android etc.
Update: I've added a crud sample in my rsocket sample codes, and I have published a post on Medium.
We are converting some code from .NET Framework to .NET Core. Some services are using SOAP messages with a signed header. Using SoapCore we've been abled to create a service which supports signed XML (and the necessary validations). However, we are now creating a client which should be able to consume such a service (in .NET Core).
Basic code (performing the request, no signing):
var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri("https://myserver/mysoapendpoint/"));
var channelFactory = new ChannelFactory<ISampleService>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var result = serviceClient.Ping("hey");
I can't find any way to make the service send an XML. In .NET Framework we could do it the following way:
using (ChannelFactory<ISampleService> factory = new ChannelFactory<ISampleServiceChannel>(tokenBinding, endpointAddress))
{
factory.Credentials.UseIdentityConfiguration = true;
using (ISampleServiceChannel proxy = factory.CreateChannelWithIssuedToken(myToken))
{
var result = proxy.Ping("hey");
}
}
Stuff like CreateChannelWithIssuedToken no longer seems to be implemented in .NET Core. If I could inject something which would sign the XML than I could do the writing myself. However, I'm unable to find the correct way to achieve this goal.
We cannot change to another implementation of security as we are not controlling the clients/services... (Clients from different organizations will interact this way...)
Many thanks for your replies.
I'm new to WCF, but not new to C# and .Net. and am using Visual Studio 2008 and .Net 3.5.
I'm trying to build a Web Service that can receive any inbound Request XML and any namespaces. It would behave like a transparent receiver and simply intake the inbound request XML.
Once I get the request I'm going to pass it to some custom .Net C# Project to invoke a MQPUT to IBM MQ Series.
Right now I have the WCF Web Service Application receiving a generic inbound operation called RunTest(). I consume the WSDL into SoapUI, build a sample request and breakpoint and it works. But, when I try to pass our company request XML it doesn't land on the breakpoint.
Here is the ServiceContract and Operation:
[ServiceContract(Name="IService1",Namespace="cfg-env=http://www.co.com/schemas/cfg- env/")]
//[ServiceContract]
public interface IService1
{
[OperationContract]
void RunTest();
[OperationContract]
void CFX();
Here is the Method for the Operation:
public void RunTest()
{ <<<it does break here using the request from the WSDL
string serviceName;
string queueManager;
string queue;
string requestMessage;
//Capture the Service Name
serviceName = "";
//Save the QueueManager
queueManager = "";
//Save the Request Queue
queue = "";
//Save the Message
requestMessage = "";
//Call MQ Put
Engine eng = new Engine();
try
{
eng.Put(serviceName, queue, requestMessage, queueManager);
}
The main thing I need to do is receive the inbound XML, interogate it for a few pieces of information and call this Method to do the MQPUT function on MQ.
The inbound namespace will look like the above but I'd like to ensure I can receive and interogate any XPATH that may be namespace qualified. If I have to I can work with the cfg-env namespace prefix exclusively as our services do use that as a standard.
What are my key hurdles in doing this in VS 2008 WCF? If you have any links please pass them along if you can.
I believe you specify the name property on the OperationContract attribute as "*" to accept all requests. To make the parameter itself schema agnostic, it should be of type System.ServiceModel.Channels.Message.
What you are building is a "WCF router".
Included in the latest .NET release is a configurable Routing Service.
If the routing service doesn't meet your needs, building your own router is possible but can get really complicated when secure messages are a requirement. This set of MSDN articles is the best resource. They answer your question of how to have a service accept any message, and then continue on into addressing and security issues.
Building a WCF Router, Part 1
Building a WCF Router, Part 2
I've been using the WCF Web Api recently and i've been using the WCF Web API Test Client that is built in to it to test my created webservices.
I am wanting to create a proxy in code built off of the interface rather than run svcutil.exe to create a proxy.
My webservice is working fine, however when I use fiddler to examine the message that is sent, it is putting in a namespace into the xml message.
Below is the code I use to send the request.
RegisterRequest registerRequest = new RegisterRequest
{
Email = "test#test.com",
Firstname = "firstname",
Lastname = "lastname",
Password = "password"
};
var factory = new ChannelFactory<IAccountApi>(new WebHttpBinding(), "http://localhost/WebServices/api/account");
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
var proxy = factory.CreateChannel();
proxy.Register(registerRequest);
This request below is generated via the client, and it fails, returning a 500 internal server error
<RegisterRequest xmlns="http://schemas.datacontract.org/2004/07/ServiceModel.Accounts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Email>test#test.com</Email><Firstname>firstname</Firstname><Lastname>lastname</Lastname><Password>password</Password></RegisterRequest>
Using the same headers when I send using the api test client the following message passes
<RegisterRequest><Email>test#test.com</Email><Firstname>firstname</Firstname><Lastname>lastname</Lastname><Password>password</Password></RegisterRequest>
The only difference being the namespace has been removed.
Some final points,
1) If I were able to remove this namespace the request would work
2) I am not sure if ChannelFactory can be used in conjunction with WCF Web Api. The reason being http://wcf.codeplex.com/releases/view/73423 states "[ServiceContract] is no longer required on the Web API class definition", yet Channel Factory requires it.
3) All the examples so far from the WCF Web API look like the following
HttpClient client = new HttpClient();
Contact contact = new Contact() { Name = name };
var response = client.Post("http://localhost:9000/api/contacts/",
new ObjectContent<Contact>(
contact, JsonMediaTypeFormatter.DefaultMediaType));
Should I be using HttpClient for my requests instead of channel factory?
Regards,
Andrew
It appears that the IAccountApi, which you do not show, is defining a namespace for the service contract. If you really want an empty namespace (not best practice) try something like this:
[ServiceContract(Namespace="")]
public interface IAccountApi
{ ... }
If the namespace is not defined for IAccountApi, check the [DataContract] of RegisterRequest.
I ended up using HttpClient class, it allows GET, POST, PUT and DELETE which was fine for WCF Web API (now called http://www.asp.net/web-api)
http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.aspx
as far as building a rest proxy using codegen or being dynamic see this article
ReST Proxy Object Generator
I created some POX services using the REST Starter kit.
At first, it was a little complicated to create the unit tests for the service layer, but in the end, it was well designed and I succeed in mocking the context and set expectations.
But, I'm starting in with the client side now, and I'm having some problems figuring out how to mock things. It's not so straight forward.
So, I have this sample method that post via HTTP some data using a datacontract and XML as transport.
public class ServiceClient: IService
{
private const string uri_template = "http://{0}:{1}/SomeService.svc/";
private readonly HttpClient http = new HttpClient();
public ServiceClient(string host, int port)
{
http.BaseAddress = new Uri(string.Format(uri_template , host, port));
}
public void Create(MyDataContract my_data_contract)
{
var content = HttpContentExtensions
.CreateDataContract(
my_data_contract,
Encoding.Default,
"text/xml",
null);
var response = http.Post("Create", content);
if (response.StatusCode != HttpStatusCode.Created) {
throw new Exception("something is not right");
}
}
}
This method is working and indeed posting the data and serializing correctly.
What I want to do, is to unit test it.
My questions are:
How do I make stubs/mocks for HttpContextExtensions knowing that it does not implement any interface?
And for HttpClient? this is worst since it is full of extension methods defined elsewhere (Post and the like methods are extensions).
In 2. I guess I can stick to 'Send' and it's overloads, but then is the same problem as in 1
What I was thinking to do, is to extract interfaces for HttpContextExtensions and HttpClient, make a children for each one and implement the interfaces delegating to the parent, and then using the interfaces in my code.
But that's a lot of work IMHO.
I'm using RhinoMocks as my mocking framework so I can't mock/stub concrete classes, and I would like to stick to it, because I really think that mocking concrete classes is not very elegant.
So, is there a cleaner/faster/smarter way to unit test code like the above?
PD: This is for WCF Starter Kit preview 2
If you really want to mock that code, an approach that could work for this scenario is to receive an HttpClient instance in the ServiceClient class. The HttpClient class contains a processing pipeline that you can customize with custom handlers. For your tests, you can basically inject a handler in that httpclient instance to return a mocked response to the test before the real service is called in the last handler (Transport Stage). Take a look at this post to get an idea about how this can be implemented,
http://weblogs.asp.net/cibrax/archive/2009/03/18/negotiating-a-saml-token-for-rest-clients-with-httpclient.aspx
Regards,
Pablo.
I wrote most of the HttpClient code. Pablo's suggestion is what I did in the unit tests -- see FixedTransport.cs in the source zip.