is it possible to call Web service by using HTTP Client ?
if yes give me some examples. How can i get list of Methods present in that web service?
for example :
I am using this Web Service WSDL link
it has two functions FahrenheitToCelsius and CelsiusToFahrenheit
Note :
i know how to call webservice by using Web Client but i need to perform call webService by using HTTP Client
Yes, you can. E.g. with Apache HttpClient 4.2.1.
import java.io.File;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Content;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
public class HttpClientPost {
public static void main(String[] args) throws ClientProtocolException, IOException {
String request = "<soapenv:Envelope response xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:tem=\"http://tempuri.org/\"><soapenv:Header/><soapenv:Body>" +
"<tem:CelsiusToFahrenheit><tem:Celsius>100</tem:Celsius>" +
"</tem:CelsiusToFahrenheit></soapenv:Body></soapenv:Envelope>";
Content response = Request.Post("http://www.w3schools.com/webservices/tempconvert.asmx")
.bodyString(request, ContentType.TEXT_XML).execute().returnContent();
System.out.println("response: " + response);
}
}
For the methods look at the elements named operation within the WSDL file.
It sure is, as long as the web service is exposed by the HTTP protocol. But you'd have to parse the response yourself, and construct valid requests yourself. Much easier to use a framework like Apache Axis, which has all of this automated.
You should also note that this web service is using the SOAP protocol, which should be accounted for when you're trying to use it.
Related
I am making a basic Hello World Web Service with help of some tutorials online.
I made a basic Java Project(non dynamic) in Eclipse. On running the code as Java Application and visiting the URL "http://localhost:9292/ws/hello" I receive"localhost page isn't working-ERR_EMPTY_RESPONSE" on my browser.Following is the code. Please let me know what am I doing wrong.
SayHello.java
package com.example.hello;
import javax.jws.WebMethod;
import javax.jws.WebService;
#WebService
public class SayHello {
#WebMethod
public String getHello(String name) {
return "Hello " + name;
}
}
LaunchService.java
package com.example.hello;
import javax.xml.ws.Endpoint;
public class LaunchService {
public static void main(String[] args) {
Endpoint.publish("http://localhost:9292/ws/hello", new SayHello());
}
}
#WebService and associated annotations are used for JAX-WS which are SOAP Web services. Requests to the service are made via POST so that is why your GET does not work. GET for ?WSDL is request for service descriptor.
With SOAP client it will work fine (e.g. SOAP UI)
if you want to build REST service then use JAX-RS or Restlet or something else
(2 years late to the party but I thought I might help someone :) )
I'm making a Java Web Application but I'm newbie in Java.
I have a Servlet (/locatemodules) that try to find other servlets in the server (/modules/*), currently the servlet find the name of the other servlets (/modules/logout, /modules/invoice, etc), but I need to get some properties and call methods to the discovered servlets, the properties and methods are the same in all servlets.
Calling like: discoveredServlet.getMenuItem();
getMenuItem returns some values, menuName, menuUrl, sideMenu[], sideUrl[], etc... to make a menu item in the web application dinamically, the discovered servlets has the post and get for when is called on the main menu.
I'm find Inter Servlet Communication articles, but unfourtunally doesn't work with API 2.2 and later.
How can get a solution like this?
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Loaded extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
ServletContext context = getServletContext();
Enumeration names = context.getServletNames();
while (names.hasMoreElements()) {
String name = (String)names.nextElement();
Servlet servlet = context.getServlet(name);
out.println("Servlet name: " + name);
out.println("Servlet class: " + servlet.getClass().getName());
out.println("Servlet info: " + servlet.getServletInfo());
out.println();
}
}
}
Servlets are the classes that are supposed to accept requests on servers and respond them.
As you are making an HTTPServlet so it is supposed to accept an http request via http methods like get and post (so you get methods doGet() and doPost() in servlets), and then servlet processes the request and sends the http response.
If you want to communicate between servers then you should set some attributes using setAttribute() method and then redirect (using response.sendRedirect()) or forward your request to another servlet and use getAttribute() method to receive values.
Servlets are not meant to be used like normal classes, that you make objects of servlet class and call its methods.
As a design principle, Servlets should only be used to receive requests from the container, invoke classes that contain business logic, and redirect to a JSP that shows the response (MVC pattern). All the business logic should be on clases that are decoupled from the HTTP protocol.
So, I think the best thing you could do, is to remove these menu related methods from your servlets, put them on POJOs, and invoke this POJOs from your servlets.
Also, remember that normally, Servlets are Singletons.
I have a class which implements the ClientRequestFilter for the Client-side filtering.
import java.io.IOException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.client.ClientRequestFilter;
import org.glassfish.jersey.server.ContainerRequest;
#Provider
public class checkRequestFilter implements ClientRequestFilter{
#Override
public void filter(ClientRequestContext clientRequestContext) throws IOException {
System.out.println("I am in checkResponseFilter");
}
}
But I don't know what to do so that I will be able to call this filter?
Do we need to add some kind of servlets in web.xml ?
A ClientRequestFilter acts on the client side. Thus, you don't have to add it to the servlet, but to the client (assuming you are using Jersey client API).
When you build your client you do something like this:
Client client = ClientBuilder.newClient();
client.register(new CheckRequestFilter()); // your filter
// more filters
WebTarget target = client.target(....
You can find a nice example over here on authentication support:
https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/client.html#d0e5464
and this one on filters
https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/client.html#d0e4391
If you meant to use a filter on the server side, you need to use ContainerRequestFilter.
Another option to do this:
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
cb = ClientBuilder.newBuilder();
client = cb.register(new checkRequestFilter()).build();
Also note that this is a client side filter, so you are trying to filter a request (not a response) that you send (hence you register the filter on your client).
so lets say, i am listening on URL v1/shop/{PATH_PARAM}/status.xml. Whenever, a request is made at v1/shop/some_value/status.xml It will be redirected to my method.
But lets say, a user does a mistake in this path ? Jersey would by itself send an response of "Bad Request" or "Un implemented" method or something like that. Is there a way that instead jersey sending this response, I can handle those reponse ? lets say i will create a new function which will listen ot everything except for those which i are implemented for business case. So any request, which is not properly structured, or some unsupported media request would go to this method, so that i can send a more resonable response to the user
You could make a Servlet Filter, configure it to intercept all URLs matching your Web Services root URL (or even the root URL of the web server where the web service is deployed), have it pass the request on to the web service and then when the response arrives at the filter, if it's some kind of web service error you can change the response to whatever you want, make it redirect to some custom error page, etc.
I just did this using an "Exception Mapper". Here is a tutorial on how to do it with resteasy: https://community.jboss.org/wiki/RESTEasyExceptionHandlingWithExceptionMapper?_sscc=t
A colleague told me there is something analogous for Jersey.
Here is the code I used to make sure that I don't get empty content, because sometimes I forget, and I'm sure others will forget, to look at the headers / HTTP status.
import org.jboss.resteasy.spi.Failure;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
#Provider
public class PipelineMgrExceptionMapper implements ExceptionMapper<Exception> {
#Override
public Response toResponse(Exception e) {
if (e instanceof Failure) {
Failure f = (Failure) e;
return Response.fromResponse(f.getResponse()).entity(f.getMessage()).type(MediaType.TEXT_PLAIN).build();
} else {
return Response.status(500).entity(e.getMessage()).type(MediaType.TEXT_PLAIN).build();
}
}
}
I'm using JAX-RS 1.0. The server verifies that a custom HTTP header is present before processing the request.
I would like to make this some sort of AOP-like behavior for the JAX-RS client, where it automatically adds the HTTP header to every request.
Does JAX-RS 1.0 support outbound client interceptors? I cant find any mention of it in the documentation. The alternative is I write a CXF-specific outbound interceptor... Thanks!
You can write a #PreMatching interceptor
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import java.io.IOException;
#PreMatching
public class ContentTypeFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext)
throws IOException {
requestContext.getHeaders().putSingle("Content-Type", "application/json");
}
}
There is no good way to do this with JAX-RS 1.0. I used CXF interceptors.
Well, JAX-RS is an API, so should be able to provide your own implementation for it. How about implementing javax.ws.rs.client.ClientFactory, and returning pre-configured javax.ws.rs.client.Client from getClient(). Should work fine as long as your class doesn't conflict from JAX-RS implementation you're using.