how to generate entire response code from http request in java? - java

I have a code but it is printing only the status, what i want is my code to prnt the entire code "Response" on console.
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
public class API{
public static void main(String args[]) throws IOException
{
URL url = new URL("http://testpath");
HttpURLConnection http = (HttpURLConnection)url.openConnection();
int statusCode = http.getResponseCode();
System.out.println(statusCode);
}
}

Your class is named API yet you seem to not have carefully read the API for HttpURLConnection. :[
getResponseMessage() is probably what you want.
If you want access to certain headers you will need to use the properties defined in URLConnection
The following methods are used to access the header fields and the contents after the connection is made to the remote object:
getContent
getHeaderField
getInputStream
getOutputStream
Certain header fields are accessed frequently. The methods:
getContentEncoding
getContentLength
getContentType
getDate
getExpiration
getLastModifed

This must work..
String statusCode = http.getResponseMessage();
System.out.println(statusCode);

Use getResponseMessage() method from HttpURLConnection to get completer response message

Related

Using Github API to retrieve list commit SHAs

I'm trying to use Github APIs to get a list of the SHAs corresponding to each commit on a given repository.
I've tried using this API:
https://api.github.com/repos/:owner/:repo/commits
And this return a list of commit object each of them containg its SHA.
The problem is that I perform this API request through a java program but the response always gets empty body and 200 as status code.
The program I'm using is this:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
public class IntermediateStructureMaker {
public static void main(String[] args) {
// create client
HttpClient client = HttpClient.newHttpClient();
// create request
HttpRequest request = HttpRequest
.newBuilder().uri(URI.create("https://api.github.com/repos/jithin-renji/Nuke/commits"))
.build();
// use the client to send the request
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
If I set the parameter ?per_page=1 in the request, I get the expected response; so I guess it's a problem of size of the response.
As solution I thought to only ask the SHA of the commits through the API request, is it possible?

How to call a web service [duplicate]

I'm relative new to the webservices world and my research seems to have confused me more than enlighten me, my problem is that I was given a library(jar) which I have to extend with some webservice functionality.
This library will be shared to other developers, and among the classes in the jar will be classes that have a method which calls a webservice (that essentially sets an attribute of the class, does some business logic, like storing the object in a db, etc and sends back the object with those modifications). I want to make the call to this service as simple as possible, hopefully as simple so that the developer using the class only need to do.
Car c = new Car("Blue");
c.webmethod();
I have been studying JAX-WS to use on the server but seems to me that I don't need to create a wsimport in the server nor the wsimport on the client, since I know that both have the classes, I just need some interaction between classes shared in both the server and the client. How do you think makes sense to do the webservice and the call in the class?
I understand your problem boils down to how to call a SOAP (JAX-WS) web service from Java and get its returning object. In that case, you have two possible approaches:
Generate the Java classes through wsimport and use them; or
Create a SOAP client that:
Serializes the service's parameters to XML;
Calls the web method through HTTP manipulation; and
Parse the returning XML response back into an object.
About the first approach (using wsimport):
I see you already have the services' (entities or other) business classes, and it's a fact that the wsimport generates a whole new set of classes (that are somehow duplicates of the classes you already have).
I'm afraid, though, in this scenario, you can only either:
Adapt (edit) the wsimport generated code to make it use your business classes (this is difficult and somehow not worth it - bear in mind everytime the WSDL changes, you'll have to regenerate and readapt the code); or
Give up and use the wsimport generated classes. (In this solution, you business code could "use" the generated classes as a service from another architectural layer.)
About the second approach (create your custom SOAP client):
In order to implement the second approach, you'll have to:
Make the call:
Use the SAAJ (SOAP with Attachments API for Java) framework (see below, it's shipped with Java SE 1.6 or above) to make the calls; or
You can also do it through java.net.HttpUrlconnection (and some java.io handling).
Turn the objects into and back from XML:
Use an OXM (Object to XML Mapping) framework such as JAXB to serialize/deserialize the XML from/into objects
Or, if you must, manually create/parse the XML (this can be the best solution if the received object is only a little bit differente from the sent one).
Creating a SOAP client using classic java.net.HttpUrlConnection is not that hard (but not that simple either), and you can find in this link a very good starting code.
I recommend you use the SAAJ framework:
SOAP with Attachments API for Java (SAAJ) is mainly used for dealing directly with SOAP Request/Response messages which happens behind the scenes in any Web Service API. It allows the developers to directly send and receive soap messages instead of using JAX-WS.
See below a working example (run it!) of a SOAP web service call using SAAJ. It calls this web service.
import javax.xml.soap.*;
public class SOAPClientSAAJ {
// SAAJ - SOAP Client Testing
public static void main(String args[]) {
/*
The example below requests from the Web Service at:
https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit
To call other WS, change the parameters below, which are:
- the SOAP Endpoint URL (that is, where the service is responding from)
- the SOAP Action
Also change the contents of the method createSoapEnvelope() in this class. It constructs
the inner part of the SOAP envelope that is actually sent.
*/
String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx";
String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit";
callSoapWebService(soapEndpointUrl, soapAction);
}
private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();
String myNamespace = "myNamespace";
String myNamespaceURI = "https://www.w3schools.com/xml/";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);
/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<myNamespace:CelsiusToFahrenheit>
<myNamespace:Celsius>100</myNamespace:Celsius>
</myNamespace:CelsiusToFahrenheit>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace);
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace);
soapBodyElem1.addTextNode("100");
}
private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Send SOAP Message to SOAP Server
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);
// Print the SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();
soapConnection.close();
} catch (Exception e) {
System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
e.printStackTrace();
}
}
private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
/* Print the request message, just for debugging purposes */
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");
return soapMessage;
}
}
About using JAXB for serializing/deserializing, it is very easy to find information about it. You can start here: http://www.mkyong.com/java/jaxb-hello-world-example/.
Or just use Apache CXF's wsdl2java to generate objects you can use.
It is included in the binary package you can download from their website. You can simply run a command like this:
$ ./wsdl2java -p com.mynamespace.for.the.api.objects -autoNameResolution http://www.someurl.com/DefaultWebService?wsdl
It uses the wsdl to generate objects, which you can use like this (object names are also grabbed from the wsdl, so yours will be different a little):
DefaultWebService defaultWebService = new DefaultWebService();
String res = defaultWebService.getDefaultWebServiceHttpSoap11Endpoint().login("webservice","dadsadasdasd");
System.out.println(res);
There is even a Maven plug-in which generates the sources: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html
Note: If you generate sources using CXF and IDEA, you might want to look at this: https://stackoverflow.com/a/46812593/840315
Might help for someone who have xml request as string.
if you have WSDL, You can create a new soap request in SoapUI with that WSDL file.
It would automatically generate the Structure/XML for input request.
Here is some simple version of Java code you can use to call Soap service if you have the input request xml from SoapUI:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class SimpleSoapClient {
public static void main(String args[]) throws IOException {
String address="Hyderabad";
/* place your xml request from soap ui below with necessary changes in parameters*/
String xml="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://www.YourUrlAsPerWsdl.com/\">\r\n" +
" <soapenv:Header/>\r\n" +
" <soapenv:Body>\r\n" +
" <ws:callRest>\r\n" +
" <name>"+"Hello"+"</name>\r\n" +
" <address>"+address+"</address>\r\n" +
" </ws:callRest>\r\n" +
" </soapenv:Body>\r\n" +
"</soapenv:Envelope>";
String responseF=callSoapService(xml);
System.out.println(responseF);
}
}
static String callSoapService(String soapRequest) {
try {
String url = "https://gogle.com/service/hello"; // replace your URL here
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// change these values as per soapui request on top left of request, click on RAW, you will find all the headers
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","text/xml; charset=utf-8");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(soapRequest);
wr.flush();
wr.close();
String responseStatus = con.getResponseMessage();
System.out.println(responseStatus);
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// You can play with response which is available as string now:
String finalvalue= response.toString();
// or you can parse/substring the required tag from response as below based your response code
finalvalue= finalvalue.substring(finalvalue.indexOf("<response>")+10,finalvalue.indexOf("</response>")); */
return finalvalue;
}
catch (Exception e) {
return e.getMessage();
}
}
}
I found a much simpler alternative way to generating soap message.
Given a Person Object:
import com.fasterxml.jackson.annotation.JsonInclude;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Person {
private String name;
private int age;
private String address; //setter and getters below
}
Below is a simple Soap Message Generator:
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
#Slf4j
public class SoapGenerator {
protected static final ObjectMapper XML_MAPPER = new XmlMapper()
.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.registerModule(new JavaTimeModule());
private static final String SOAP_BODY_OPEN = "<soap:Body>";
private static final String SOAP_BODY_CLOSE = "</soap:Body>";
private static final String SOAP_ENVELOPE_OPEN = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
private static final String SOAP_ENVELOPE_CLOSE = "</soap:Envelope>";
public static String soapWrap(String xml) {
return SOAP_ENVELOPE_OPEN + SOAP_BODY_OPEN + xml + SOAP_BODY_CLOSE + SOAP_ENVELOPE_CLOSE;
}
public static String soapUnwrap(String xml) {
return StringUtils.substringBetween(xml, SOAP_BODY_OPEN, SOAP_BODY_CLOSE);
}
}
You can use by:
public static void main(String[] args) throws Exception{
Person p = new Person();
p.setName("Test");
p.setAge(12);
String xml = SoapGenerator.soapWrap(XML_MAPPER.writeValueAsString(p));
log.info("Generated String");
log.info(xml);
}

jquery ajax returns element not found

I have a REStful webservice (java, jersey) to do some stuff.
every function that calls an ajax request (GET or POST) with an url to the REST controller works fine... except of the recent ones and I do not know why.. i tried everything and stuck with this problem for nearly three days (wrote 3 different functions, changed from GET to POST, rewrote the function with new pathannotiation, tried to call on pageload.. renamed everything), I realy appreciate ANYTHING that could help me...
if the url contains rest/* the controller forwards it to the class which implements the needed functions..
JS function
function testFunc() {
$.ajax({
url: "rest/name/wut",
type: "GET",
contentType: "application/json;charset=utf-8",
success: function(response) {
alert("LSKDFJLSDKJFLKSD " + response);
},
error: function(response) {
alert("ma oidaaaa " + JSON.stringify(response));
}
});
};
Java Code in the RESTClass...
#GET
#Path("/wut")
#Produces(MediaType.APPLICATION_JSON)
private String wut() {
JSONObject json = new JSONObject();
json.put("print", "wuut");
return json.toString();
}
It does not matter if the method is doing anything useful or not... it just returns 404 no element found.
(it is not even called) Therefore i tried different new methods in the RESTClass... like:
#GET
#Path("/wut")
#Produces(MediaType.APPLICATION_JSON)
private String wut() throws IOException {
URL url = new URL(url);
StringBuffer response = new StringBuffer();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
I am using this snipped in another method, which is working.. I replaced the real URL with "url" for posting btw.
I also tried different MediaTypes: WILDCARD, TEXT/PLAIN...
And to just return a String...
Anyone any ideas (and SORRY for the bad english, I am really desperate so i did not do a spellcheck and english is not my native :( )
Two ideas:
First, declare your wut() method as public: public String wut()
Second, try to call your method in a browser, for example http://localhost/rest/name/wut and see what happens
I would try to use an absolute path:
Change:
url: "rest/name/wut",
to
url: "/rest/name/wut",
The error message tells me that, your client did not try the address the server provides.

Send and receive JSON to REST WebService in Jersey Java

I am new to Jersey Java REST WebService framework. I am trying to write a service method which consumes and produces JSON. My service code is below. It is simplest code, just for studying purpose.
#Path("/myresource")
public class MyResource {
#Path("/sendReceiveJson")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String sendReceiveJson(String name)
{
System.out.println("Value in name: " + name);
return "{\"serviceName\": \"Mr.Server\"}";
}
}
And following is JerseyClient code.
public class Program {
public static void main(String[] args) throws Exception{
String urlString="http://localhost:8080/MyWebService/webresources/myresource/sendReceiveJson";
URL url=new URL(urlString);
URLConnection connection=url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write("{\"clientName\": \"Mr.Client\"}");
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}
But when i run service and then client, i am unable to send/receive JSON data. I get Exception at connection.getInputStream() which is
Server returned HTTP response code: 405 for URL: http://localhost:8080/hellointernet/webresources/myresource/sendReceiveJson
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
Please guide me, what needs to correct, or whether i am in wrong direction.
Your resource method is annotated as #GET which means any input data would have to be query string parameters.
In this context #Consumes(MediaType.APPLICATION_JSON) doesn't make a lot of sense as only APPLICATION_FORM_URLENCODED is supported via GET.
When you client calls setDoOutput(true) it probably switches your HTTP call to a POST hence causing the 405 Method Not Allowed.
If you want to consume JSON you should change your #GET annotation with #POST instead. Your client call should then work if it's indeed a POST. You can specify it with the following method:
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setDoOutput(true);
httpCon.setRequestMethod("POST");
This API is pretty low level though, so I'd highly recommend you use Jersey's Client API instead. See https://jersey.java.net/documentation/1.17/client-api.html

How to recursively call servlet from same servlet

I would like to recursively call a servlet from itself until my operation completes. The reason I need to do this is because my hosting service has a hard deadline that must be met for all RPC calls. Therefore, I need to break up the operation in managable chunks and call the servlet recursively for each chunk until the operation completes.
I feel like the following code should work, but it is not calling the servlet when the HttpURLConnection is opened and connected. No errors are being thrown either. Any help would be greatly appreciated.
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#SuppressWarnings("serial")
public class ServletExample extends HttpServlet {
HttpServletRequest request;
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
request = req;
String strRequestIndex = request.getParameter("requestIndex");
int intRequestIndex = 0;
if (strRequestIndex != null) {
intRequestIndex = Integer.parseInt(strRequestIndex);
}
if (intRequestIndex < 10) {
try {
callSameServlet(intRequestIndex);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void callSameServlet(int requestIndex) throws Exception {
URL recursiveUrl = new URL(request.getRequestURL().toString()
+ "?requestIndex=" + (requestIndex + 1));
HttpURLConnection connection = (HttpURLConnection) recursiveUrl
.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.connect();
DataOutputStream dos = new DataOutputStream(
connection.getOutputStream());
dos.flush();
dos.close();
}
}
As to the technical problem as exposed in your question: the URLConnection is lazily executed. The URLConnection#getOutputStream() in your code only returns a handle to write the request body. You need to use URLConnection#getInputStream() to actually fire the HTTP request and obtain the response body.
See also:
How to use URLConnection to fire and handle HTTP requests?
There are however more problems in your code:
You're firing a POST request, but there's nowhere a doPost() method in your servlet definied. You need to either fire a normal GET or to implement doPost(). But that'll be obvious by investigating the obtained error response as described in the above link.
Also, your servlet is not threadsafe. You should never declare/assign request/session scoped data as instance variable of the servlet. Read this answer to learn more.
Finally, did you consider using RequestDispatcher#include() instead? That will be handled internally and saves you the cost/overhead of firing HTTP requests.
request.getRequestDispatcher("servleturl").include(request, response);
You can then use request attributes instead of request parameters. The whole functional requirement makes little sense by the way. I'd just use a for or while loop on the code you'd like to execute recursively. But that's a different problem.

Categories