call java web service from javascript - java

I would like to call my webservice methods from pure java script code. and that code should work on mozilla browser.
This is my webservice code:
package com.example.core;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
#WebService
public class Area {
#WebMethod
public double square(#WebParam(name="side") double side)
{
return side * side;
}
#WebMethod
public double rectangle(#WebParam(name="length") double length,#WebParam(name="breadth") double breadth)
{
return length * breadth;
}
public static void main(String[] args) {
Area area = new Area();
String url = "http://localhost:8090/area"; // end point of webservice.
System.out.println(url+"?wsdl");
Endpoint.publish(url, area); // publishing the webservice
}
}
Here is my HTML file:
<html>
<head>
<meta content="utf-8" http-equiv="encoding">
<meta content="text/xml;charset=utf-8" http-equiv="Content-Type">
<script language="javascript">
function call()
{
var side = sideid.value;
var side1 = sideid1.value;
var req = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://core.codon.com/\"><soapenv:Body><web:rectangle><length>" + side+ "</length><breadth>" + side1+ "</breadth></web:rectangle></soapenv:Body></soapenv:Envelope>";
//var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
//var reqXML = xmlDoc.loadXML(req);
var xmlDoc=document.implementation.createDocument("", "", null);
xmlDoc.async=false;
xmlDoc.onload = req;
//var reqXML = xmlDoc.load(req);
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
var response = xmlhttp.responseXML;
alert(response.selectSingleNode(".//return").text);
alert("======"+response);
}
}
var soapaction = "http://core.example.com/rectangle";
xmlhttp.open("POST","http://localhost:8090/area?wsdl",true);
xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlhttp.setRequestHeader("SOAPAction", soapaction);
xmlhttp.send(req);
}
</script>
</head>
<body>
Side Length: <input type="text" id="sideid"></input>
Length: <input type="text" id="sideid1"></input>
<button onclick="call();">area of square</button>
</body>
</html>
with the above code am getting response as null. The same code working on IE but not in mozilla...
my webservice side am getting the following error
com.sun.xml.internal.ws.transport.http.server.WSHttpHandler handleExchange
WARNING: Cannot handle HTTP method: OPTIONS
Please Help me out..Thanks in advance

I would take SOAP UI, generate web service client, generate example requests, so I don't need to create SOAP envelopes from scratch. Then I would use jQuery to generate AJAX requests with the help of generated SOAP envelopes.
Another approach would be to make use of http://cxf.apache.org/docs/javascript-clients.html - you will have complete JavaScript generated that way.

You are running webservice as stand alone app on port say 'x' and the client might be on another port say 'y'
When you do a post call through y onto x the method will always be changed to options automatically. Internet standards wont allow 'posting' between different servers, I guess.
You will have to find another workaround.

Related

Passing data from Servlet to JSP (real time)

I have a device which sends a JSON message via HTTP POST, to a web server. The server receives the JSON message as payload and decodes and prints it on the web page and also sends back a 200 OK response to the post.
Now, I am trying to replicate the same with a fake Java client code to act as the device and a fake server using servlet and JSP.
The servlet code and JSP run as one project and the Java code run as another project.
I am using Eclipse and Tomcat server.
My code is as follows:
Servlet Code:
(This is saved in Java Resources > src > DefaultPackage)
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import org.json.JSONException;
import org.json.JSONObject;
#WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuilder sb = new StringBuilder();
BufferedReader reader = request.getReader();
try {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} finally {
reader.close();
}
System.out.println(sb.toString());
String api_key = null;
try {
//JSONObject jsonObj = new JSONObject(sb.toString().substring(sb.toString().indexOf('{')));
//JSONTokener t = new JSONTokener(sb.toString());
JSONObject obj = new JSONObject(sb.toString().replace("\uFEFF", ""));
System.out.println(obj.toString());
api_key= (String) obj.get("api_key");
//String node_number = (String) obj.get("node_number");
//String tag_statuses = (String) obj.get("tag_statuses");
//String voltage = (String) obj.get("voltage");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("api_key:"+ api_key+"\n");
response.setStatus(response.SC_OK);
//response.setContentType("text/html");
//PrintWriter out = response.getWriter();
//out.println("<h1>"+out +"</h1>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/NewFile.jsp");
request.setAttribute("api_key", api_key); // set your String value in the attribute
dispatcher.forward( request, response );
}
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
doPost(req, res);
}
}
JSP Code:
(saved in WebContent)
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<td><%=request.getAttribute("api_key")%></td>
</tr>
</table>
</body>
</html>
Java Application Code:
import java.io.*;
import java.net.*;
import org.json.JSONObject;
public class Client {
public static void main( String [] args ) {
try
{
JSONObject jsonObj = new JSONObject("{\"api_key\" : \"rien\", \"node_number\" : \"40\", \"tag_statuses\" : [[100,\"MISSING\"]], \"voltage\": \"345\", \"location\": [42.3432,23.0098]}");
URL url = new URL("http://localhost:95/sample/HelloWorld");
URLConnection uc = url.openConnection();
HttpURLConnection conn = (HttpURLConnection) uc;
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-type", "application/json");
PrintWriter pw = new PrintWriter(conn.getOutputStream());
//pw.write(jsonObj.toString());
pw.write(jsonObj.toString());
pw.close();
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
bis.close();
int responseCode = conn.getResponseCode();
System.out.println("Response Code recieved is: " + responseCode);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Here, I would like to see the content received by the servlet to be updated on the JSP, whenever some new content appears on the servlet, maybe by refreshing the webpage.
Now, When I try to run the code, without a jsp page I am receiving the content from the application and the java application is getting a 200 status update.
But when I try to include the JSP code, the JSP will run and I get a 'null' printed on JSP, but I get the data on console of servlet and I get the following exception on Java application code (instead of a 200 status message),
java.io.FileNotFoundException: http://localhost:95/sample/HelloWorld
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at Client.main(Client.java:21)
Could someone please help me in getting the content printed on the JSP real time and to avoid the error on the Java application? What am I doing wrong here?
Thanks.
First thing I recommend you to do is to debug things not with your own client but using curl, which is stable and already tested ad nauseam.
See the following: How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?
It looks like that your response is either 500 or 404 error code. I bet 500 since your server-side does not seem to be producing a 404.
Also, consider migrating both client and server to Jersey, which already solves all your problems.
https://jersey.java.net/
But if you want to stick to your implementation, it looks like the problem is on the way you are writing your client. The client thinks that you are trying to read a file (URL may also point to files, not only network URLs). Here again Jersey is your friend since, as I said before, it also has an HTTP client library.
From my personal experience with Java Servlets and JSPs the functionality of real time updating is not achievable through the method you are implementing. This is because when the request for the JSP is rendered, it will be rendered with whatever information your app contains when the request is received, then is sent to the browser. Once in the browser is all html/css, no java scriptlets, so it won't update automatically.
You can use web sockets to achieve this live-content feature or simply run a javascript function that calls the some servlet (ajax calls), retrieve the information, and change the html content.
Example of Ajax Call for email verification, used in the old days.
$.ajax(
{
url: "/validation", //URL of request
data:
{
param1: form.email.value //Parameter that will be sent.
},
async: false, // You can make it Async.
type: "POST", // Type of request.
dataType: "text", // Expected data type, might be json.
success: function(data) // If Ajax is success it will execute this function
{
if(data=="true")
{
missingStuff =" This email is already registered \n";
correoDiv.attr("class", "form-inline has-error");
}
else
{
correoDiv.attr("class", "form-inline has-success");
}
}
}
);
Another think you might want to check out it is : Socket.io,
they offer many features for realtime content.

Http Server (Java on Vertx) not getting POST parameter

I am sending a ajax request from a client such as:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url: "http://192.168.1.74:8888",
type: "POST",
data: ({username: 'Bobby'})
});
})
</script>
</head>
<body>
</body>
</html>
My Http Server is written in Java utilizing vertx is like so:
public class Main extends AbstractVerticle {
#Override
public void start() throws Exception {
vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
#Override
public void handle(HttpServerRequest request) {
System.out.println(request.getParam("username"));
}
}).listen(8888);
}
}
Every time I run the client, the server writes to console so the request is sent, but the server says the value is null. What am I doing wrong? How do I read the POST parameter being sent from the client?
UPDATE:
I found the problem, but no solution. If I change the ajax to GET from POST then it will appear. How do I make it so it works for POST and not for GET? SO the opposite of what is occurring now?
Cheers
I encountered the problem while working on my project. I was using Dojo on the client side. I manged to solve this by making adjustments both on the client side and the server side.
Client:
var json = JSON.stringify({
"username": "Bobby"
});
request.post("yoururl", {
data: json,
headers: {
"Content-Type": "application/javascript"
}
});
On the server side, apparently, what was required was calling the method BodyHandler.create() before handling the code.
router.route(HttpMethod.POST, "yoururl").handler(BodyHandler.create());
router.route(HttpMethod.POST, "yoururl").handler(routingContext ->
{
String sectionType = routingContext.request().getParam("sectionId");
JsonObject j = routingContext.getBodyAsJson();
});
I hope this would solved your problem.
When doing a POST request the data is in the body.
On the server side you need to register a body handler for your router in order to be able to easily get the body from the request. You can do that like this:
final Router router = Router.router(vertex);
// Adding a BodyHandler for routes
router.route().handler(BodyHandler.create());
router.post("/your/endpoint").handler(routingContext -> {
System.out.println(routingContext.getBodyAsString());
});
Another option is to add another callback handler like this:
final Router router = Router.router(vertex);
router.post("/your/endpoint").handler(routingContext -> {
routingContext.request().bodyHandler(body -> {
System.out.println(body.toString());
});
});
data: {"username": 'Bobby'} will fix your issue, and remove the () also you can try to change you ajax request in jquery as follow
var datavar = {username:"someusername"}; //Array
$.ajax({
url : "AJAX_POST_URL",
type: "POST",
data : datavar,
success: function(data, textStatus, jqXHR)
{
alert("success") ;
},
error: function (jqXHR, textStatus, errorThrown)
{
alert("fail") ;
}
});

Trouble in posting data as form data in Angular JS to Java REST web-service

I am trying to create a web service in Java that accepts two lists as FormData parameter.
I have used the Angualr JS http service as mentioned in this answer.
var queryRequest = $http({
method:'POST',
url:'services/test/testPath',
data:$.param({"listA":myList1,"listB":myList2}),
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
});
My object myList1
var myList1=[];
var obj={};
obj["val1"]=1
obj["val2"]=2
myList1.push(obj);
My object myList2
var myList2=[];
var obj={};
obj["val11"]=3
obj["val12"]=4
myList2.push(obj);
var obj={};
obj["val11"]=5
obj["val12"]=6
myList2.push(obj);
I am using javax.ws.rs.* for the rest service
And my Java server endpoint, which accepts the data, is as-
#Path("testPath")
#POST
#Consumes("application/x-www-form-urlencoded;charset=UTF-8")
#Produces("application/json")
public DataDTO addIssuancesForFP(#FormParam("listA") List<TypeA> list1, #FormParam("listB") List<TypeB> list2) {
System.out.println("Service is called correctly");
return service.getDTO(list1,list2);
}
My classe 'TypeA'
private Integer val1;
private Integer val2;
//getters and setters, and default constructor
My classe 'TypeB'
private Integer val11;
private Integer val12;
//getters and setters, and default constructor
Endpoint is hitting correctly, but I am getting null in both the list. The request structure is:
Request Type
Accept:application/json, text/plain, */*
Content-Type:application/x-www-form-urlencoded;charset=UTF-8
Form Data
listA[0][val1]:1
listA[0][val2]:2
listB[0][val11]:3
listB[0][val12]:4
listB[1][val11]:5
listB[1][val12]:6
It seems to be correct, I think mistake is in server part. How to resolve this?
Thanks
Note: This is just the mock data, which is in exact same format
Yeah so I don't think using form encoded data is going to work. The reason is that it is mainly for key value pairs, in the form
key1=value7&key2=value2&key3=value3...
What you are doing is using only two keys, listA and listB. So imagine what the values would need to look like, to send the entire list. It isn't pretty. For complex data, it is more viable to send the data in a format like JSON. The problem with this for your particular use case is that there are two unrelated objects (or arrays) to needs to send. For this, a solution would be to use multipart. You're in luck, because I just posted a late answer yesterday, on exactly how this can be handled with Angular.
I won't go through an explanation here about the code. Everything is explained in that link. Please read through it, as you go through this answer. I will be using Jersey as may JAX-RS implementation (as does the example in the link - but it also offers other alternative implementations)
Resource
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/form")
public class FormResource {
#POST
#Consumes("multipart/form-data")
#Produces("text/plain")
public String addIssuancesForFP(#FormDataParam("listA") List<TypeA> list1,
#FormDataParam("listB") List<TypeB> list2) {
StringBuilder response = new StringBuilder();
for(TypeA a: list1) {
response.append(a.toString()).append("; ");
}
for (TypeB b: list2) {
response.append(b.toString()).append("; ");
}
System.out.println("Service is called correctly");
return response.toString();
}
}
Angular
<!DOCTYPE html>
<html ng-app="formApp">
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="js/libs/jquery/jquery.js"></script>
<script src="js/libs/angular.js/angular.js"></script>
<script>
angular.module("formApp", [])
.controller("defaultCtrl", function($scope, $http) {
$scope.sendData = function() {
var myList1 = [];
var obj = {};
obj["val1"] = "value1";
obj["val2"] = "value2";
myList1.push(obj);
var myList2 = [];
var obj = {};
obj["val11"] = "value11";
obj["val12"] = "value12";
myList2.push(obj);
var obj = {};
obj["val11"] = "value211";
obj["val12"] = "value212";
myList2.push(obj);
var list1 = JSON.stringify(myList1);
var list2 = JSON.stringify(myList2);
var boundary = Math.random().toString().substr(2);
var header = "multipart/form-data; charset=utf-8; boundary=" + boundary;
$http({
url: "/api/form",
headers: {"Content-Type": header},
data: createRequest(list1, list2, boundary),
method: "POST"
}).then(function(response) {
$scope.result = response.data;
});
function createRequest(list1, list2, boundary) {
var multipart = "";
multipart += "--" + boundary
+ "\r\nContent-Disposition: form-data; name=listA"
+ "\r\nContent-type: application/json"
+ "\r\n\r\n" + list1 + "\r\n";
multipart += "--" + boundary
+ "\r\nContent-Disposition: form-data; name=listB"
+ "\r\nContent-type: application/json"
+ "\r\n\r\n" + list2 + "\r\n";
multipart += "--" + boundary + "--\r\n";
return multipart;
}
};
});
</script>
</head>
<body>
<div ng-controller="defaultCtrl">
<button ng-click="sendData()">Send</button>
<p>{{result}}
</div>
</body>
</html>
Result
TypeA{val1=value1, val2=value2};
TypeB{val1=value11, val2=value12};
TypeB{val1=value211, val2=value212};
Which is expected, as I just built a string from the toString() methods, which I implemented in the TypeA and TypeB classes.
public class TypeA {
public String val1;
public String val2;
#Override
public String toString() {
return "TypeA{" + "val1=" + val1 + ", val2=" + val2 + '}';
}
}
public class TypeB {
public String val11;
public String val12;
#Override
public String toString() {
return "TypeB{" + "val1=" + val11 + ", val2=" + val12 + '}';
}
}
Hope this helps.

Javascript client code giving NS_ERROR_FAILURE

I am trying a thrift client-server hello world call.
The server is written in java and the client is in javascript.
Client.html is as follows:
<html>
<script src="thrift.js" type="text/javascript"> </script>
<script src="helloWorld.js" type="text/javascript" ></script>
<script src="callServer.js" type="text/javascript" ></script>
<body>
Test The thrift call....
<button onclick="getInfo();">Click me</button>
</body>
</html>
Above thrift.js is thrift javascript library version 8.0 and helloWorld.js is the generated js file from the following thrift idl.
service helloWorld{
string getWorld();
}
callServer.js
/*callServer.js*/
function getInfo() {
alert("reached callServer.js");
var url = "http://localhost:8080/myWebProj/HelloWorldServlet";
var transport = new Thrift.Transport(url);
var protocol = new Thrift.Protocol(transport);
var client = new helloWorldClient(protocol);
alert(client.getWorld());
}
At the server side
I have a servlet mapped in web.xml and one implementation class
public class HelloWorldServlet extends TServlet{
private static final long serialVersionUID = -3425847860067398133L;
public HelloWorldServlet() {
super(new HelloWorld.Processor(new Hworld()),
new TJSONProtocol.Factory());
}
}
public class Hworld implements HelloWorld.Iface{
#Override
public String getWorld() throws TException {
// TODO Auto-generated method stub
System.out.println(" in hello World .... ");
return "Hello World";
}
}
The sysout in above code is printed successfully when I try to hit the server.But at the client side I get NS_ERROR_FAILURE. I guess I am doing something wrong.Please help me.In case any other info is required plz post it as comment.

Multi part javascript function

The problem I am trying to solve is having a javascript function that will perform some functions in sequence.
Step 1) Web client/javascript does some functions locally to the browser.
Step 2) The browser calls a java class/application on the webserver which will perform a number of tasks that only the webserver itself (not the client) can perform.
Step 3) Have the results of step two added to the webpage and displayed in the browser without reloading all the HTML
N.B. Step 2 may take several minutes and it is ok for the client to be essentially inactive during this time.
I'd appreciate any advice or walk throughs/tutorials that may be relevant.
Kind Regards
Use jQuery to perform an asynchronous HTTP request(AJAX)
function YOURFUNCTION(){
//Calls servlet
$.post('ServletName',{parameter:value,parameter2:value2,...},function(results) {
//displays results returned from servlet in specific div(resultsDiv)
$('#resultsDiv').html(results);
});
}
You need to include the jQuery library on top of your HTML file as:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
You may find more info here
Simple as that.
i hope this concise explanation will give you an overview and the understanding you expect.
PART A
SERVER SIDE
In your web server application on your server, if using Java, you are to create a Java servlet class to process data that was submitted from client browser via script or form and to provide dynamic content such as the results of a database query from the client.
Read more on Servlets from:
http://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html
http://en.wikipedia.org/wiki/Java_Servlet
What is Java Servlet?
Also read more about how to register your servlet on the server (web.xml for java Projects)
Example of a servlet:
-================-
#WebServlet(name = "MyServlet", urlPatterns = {"/calculator"}, asyncSupported = true)
public class MyServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration e = request.getParameterNames(); // parsing the string from client
while (e.hasMoreElements()) {
String name = (String) e.nextElement();// eg. "command" from ajax
String value = request.getParameter(name); // eg. getSum
if (value.equals("getSum")) {
// Instantiate a java class and call the method
// that performs the addition and returns the value
Calculator calc = new Calculator();
String answer = (String) calc.getSum();
if (answer != null) {
// Set contentType of response to client or browser
// so that jQuery knows what to expect.
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
// return answer to ajax calling method in browser
out.print(answer);
out.close();
}
}
} // END While LOOP
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// include method if you call POST in you ajax on client side
}
}
a Java Class for calculations on your server path
public class Calculator {
public int getSum() {
return 10+15;
}
}
-
PART B
CLIENT SIDE – Your Browser
-======================-
You have to visit jQuery website, download and add the jQuery ajax script to your project. “jquery-ui.min.js” is sufficient for this purpose. Add this script to your html or jsp file using the following line:
<script src="resources/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
Within your external javascript file or inline javascript include a function to call the servlet and get the sum as follows:
function getSum(){
$.ajax({
type: 'GET', // type of request to make. method doGet of the Servlet will execute
dataType: 'text', // specifying the type of data you're expecting back from the server
url: 'calculator', // the URL to send the request to. see annotation before class declaration
data: "command="+"getSum", // Data to be sent to the server (query string)
// if request fails this method executes
error:
function(e){
alert('Error. Unable to get response from server');
},
// when request is successful, this function executes
// display the data from server in an alert
success:
function(result){
if(result) {
alert(result);
}
}
});
}

Categories

Resources