I'm trying to send JSON data from a JavaScript function using Ajax to a Servlet.
Client side:
function addObject() {
var data = {
aa: "aa",
bb: "bb"
}
var string = JSON.stringify(data);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "GalleryAdd", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
console.log("Done");
}
};
console.log(string);
xhttp.send(string);
}
Output from stringyfied data is {"aa":"aa","bb":"bb"}.
Servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
log(request.getParameter("aa"));
log(request.getParameter("bb"));
}
Output in the logger is null and null.
Looks like JavaScript does not send data to the servlet, also if it's stringifyed correctly. Anyone?
Your Json object is in the body of the request therefore you need to parse the InputStream. Try this.
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
JsonObject object = Json.createReader(req.getInputStream()).readObject();
log(object.getString("aa"));
log(object.getString("bb"));
}
Related
This question already has answers here:
Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not?
(13 answers)
CORS Java server side implementation
(2 answers)
No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
(26 answers)
Closed last year.
I'm trying to make a server in java that can handle requests sent from the browser. My problem is that I can't get the browser to actually send the request, all it sends is an OPTIONS request. Here's the error in the browser:
It isn't an actual website that I'm using, it's just an html page that would be opened by the java application. Here's the html:
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="sendRequest()">Click Me!</button>
<script>
function sendRequest() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://172.26.48.1:9000/test", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({
"time": 16400
}));
}
</script>
</body>
</html>
And here's the java server that listens for the requests:
public class ServerTest
{
public static void main(String[] args) throws Exception
{
HttpServer server = HttpServer.create(new InetSocketAddress(9000), 0);
server.createContext("/test", new MyHandler());
server.setExecutor(null);
server.start();
}
static class MyHandler implements HttpHandler
{
public void handle(HttpExchange exchange) throws IOException
{
System.out.println("Handling request: " + exchange.getRequestMethod());
if (exchange.getRequestMethod().equalsIgnoreCase("POST") ||
exchange.getRequestMethod().equalsIgnoreCase("OPTIONS"))
{
try
{
InputStream is = exchange.getRequestBody();
StringBuilder sb = new StringBuilder();
for (int ch; (ch = is.read()) != -1;)
sb.append((char) ch);
System.out.println(sb.toString());
String response = "OK";
exchange.sendResponseHeaders(200, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
exchange.close();
} catch (NumberFormatException e)
{
e.printStackTrace();
}
}
}
}
}
The server works fine, but it only receives the OPTIONS request. How can I make the html page send the actual POST request?
function sendRequest() {
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://172.26.48.1:9000/test", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Response
var response = this.responseText;
}
};
xhttp..send(JSON.stringify({
"time": 16400
}));
}
I have a button. When I click that button, Login method in the js file gets executed. Inside the Login method, I am calling an API. I am trying to fetch the output returned by the API but I am getting blank response in the alert message in the below code.
I am getting the correct response when trying to hit the API through Postman.
Here is the js code where I am calling the API-
function Login() {
var url="https://localhost:44369/categories?username="+"sid"+"&password="+"123";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
alert(xhr.responseText);
}
xhr.open('GET', url, true);
xhr.send(null);
}
Here is the get API code-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace login.Controllers
{
public class ValuesController : ApiController
{
// GET api/values
[HttpGet]
[Route("categories")]
public IHttpActionResult Get(string username,string password)
{
loginResponse response = new loginResponse();
if(username=="sid" && password== "123"){
response.Success = true;
}
else
{
response.Success = false;
}
return Ok(response);
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody] string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}
This worked for me -
var username=document.getElementById("UserName").value;
var password=document.getElementById("Password").value;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://localhost:44369/categories?username=sid&password=12', true);
xhr.send();
xhr.onreadystatechange = () => {
console.log(xhr);
if (xhr.readyState=== 4) {
console.log(xhr.response);
}
}
If you confused you can create code for JavaScript XHR in Postman, follow below steps:
I think below code works:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("GET", "https://localhost:44369/categories?username=sid&password=123");
xhr.send();
I am trying to get some dynamic buttons to send their id to my servlet. I think I am close but just cant figure out how to get the data on the backend.
HTML: (dynamically generated)
<button class="btn btn-success btn-reimb" id="${res[i][1].id}" onclick='approve(this)'><i class="fas fa-check"></i></button>
JS:
const approve = (e) => {
console.log(e.id);
const id = e.id;
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
console.log("Sending...")
}
};
xhttp.open("POST", 'approve', true);
xhttp.send(id);
}
Servlet:
#WebServlet(name = "approve", urlPatterns = {"/approve"} )
public class ApproveServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String id = req.getParameter("id");
System.out.println(id);
}
}
Thanks in advance!
EDIT:
Thanks to Nikos Paraskevopoulos! My servlet code now looks like:
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
ServletInputStream input = req.getInputStream();
StringBuilder string = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader
(input, Charset.forName(StandardCharsets.UTF_8.name())))) {
int c = 0;
while ((c = reader.read()) != -1) {
string.append((char) c);
}
}
int id = Integer.parseInt(string.toString());
System.out.println(id);
The data you send with XMLHttpRequest is in the request body. Read it with req.getInputStream(). This gives you a ServletInputStream, which you can read as a standard InputStream.
how can i pass a JSON Array/Object with the JQUERY get Method to my Java Servlet?
So far , here's my code:
var json = {
MA_ID : $("#emplID").val(),
MA_Nachname : $("#nachname").val()
}
$.get(url + "/MA_Update", json)
[...]
MA_Update.java
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringBuffer jb = new StringBuffer();
String line = null;
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
try {
JSONObject jsonObject = HTTP.toJSONObject(jb.toString());
System.out.println(jsonObject);
} catch (JSONException e) {
// crash and burn
throw new IOException("Error parsing JSON request string");
}
}
But I only get
{"Request-URI":"","Method":"","HTTP-Version":""}
from my request
Do not use request.getReader(), use request.getParameter("MA_ID") etc., or request.getParameterMap() (and iterate over it).
The thing is, that $.get(url, jsObject) creates a HTTP GET request, where the fields of the jsObject are transformed into query parameters, i.e. http://your.server.com/MA_Update?MA_ID=someID&MA_Nachname=SomeLastName, so they are NOT available in the request body (as they would be in a POST request).
I am calling this method from JavaScript.
For the first time, it is giving null. But from the second time onwards, the data is coming.
Please help me.
#SuppressLint("JavascriptInterface")
public String loadClickedData() {
pDialog = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new HttpAsyncTaskClickedData()
.execute("http://192.168.0.9/btrepo/btrepo/android_api.php");
return bdb.getmPosIdData();
}
Here we are getting data through AsyncTask in Android:
private class HttpAsyncTaskClickedData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("tag", "get_pos_details"));
nameValuePairs.add(new BasicNameValuePair("pos_id", posId));
return GET(urls[0], nameValuePairs);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
// Toast.makeText(getApplicationContext(), result+" in post ",
// Toast.LENGTH_LONG).show();
pDialog.dismiss();
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG)
.show();
bdb.setmPosIdData(result);
}
}
This method is for getting data from the server:
public static String GET(String url, List<NameValuePair> pair) {
InputStream inputStream = null;
String result = "";
try {
// create HttpClient
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pair));
HttpResponse httpResponse = httpClient.execute(httpPost);
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
is = inputStream;
// convert inputstream to string
if (inputStream != null) {
// jObj = convertIsToJson(inputStream);
result = convertIsToJson(inputStream) + " ";
// jSonStr = result;
} else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return result;
}
I am getting data from the server in json string format.
It is displaying attributes with null value like {pos["posid":null, "storeName":null]} etc..
In the following function
public String loadClickedData() {
pDialog = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new HttpAsyncTaskClickedData()
.execute("http://192.168.0.9/btrepo/btrepo/android_api.php");
return bdb.getmPosIdData();
}
You execute your HttpAsyncTaskClickedData(), and return bdb.getmPosIdData() immediately. (Which will always be an issue for the 1st time)
The result of the AsyncTask is only available in onPostExecute, where you call bdb.setmPosIdData(result);.
#Override
protected void onPostExecute(String result) {
// ...
bdb.setmPosIdData(result); // result is only stored in bdb here!
}
The HttpAsyncTaskClickedData runs in the background, and possibly takes some time.
That is why your first call is always unable to get data, as you returned bdb.getmPosIdData() immediately after executing your AsyncTask.
private class HttpAsyncTaskClickedData extends
AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs
.add(new BasicNameValuePair("tag", "get_pos_details"));
nameValuePairs.add(new BasicNameValuePair("pos_id", posId));
return GET(urls[0], nameValuePairs);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
// Toast.makeText(getApplicationContext(), result+" in post ",
// Toast.LENGTH_LONG).show();
data = result;
pDialog.dismiss();
bdb.setmPosIdData(result);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(MainActivity.this, "dialog title",
"dialog message", true);
}
#SuppressLint("JavascriptInterface")
public String loadData() {
Toast.makeText(getApplicationContext(), data+ " hi ",
Toast.LENGTH_LONG).show();
return data;
}
}
and calling loadData() method from javascript.
This function is for get data by using post url in javascript
function jsonPost(){
var http = new XMLHttpRequest();
var url = "http://192.168.0.9/btrepo/btrepo/android_api.php";
var params = "tag=fav_stores&mobile=984989874";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
alert("hello "+http.send(params));
}