Sending Data from JS to servlet without using <form> - javascript

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.

Related

Unable to send Json data from Ajax to Servlet

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"));
}

Dragging Image in CKEditor PrimeFaces

I am trying to upload image in CKEditor with image2 plugin.It is wokring fine when I am uploading it by 'send it to server' button but drag and drop of images is not working.
Below is Version Detail:
- Primefaces 6.0
- Ckeditor 4.9.1
- JSF 2.2
Config.js
CKEDITOR.editorConfig = function(config){
// config.timestamp='ABCD';
config.disableNativeSpellChecker = false;
config.pasteFromWordRemoveFontStyles=false;
config.pasteFromWordRemoveStyles=false;
config.allowedContent=true;
config.filebrowserBrowseUrl='#{request.contextPath}/CKEditorGetImageServlet';
config.filebrowserUploadUrl = 'CKEditorUploadServlet';
//config.filebrowserUploadMethod = "form";
config.uploadUrl='CKEditorUploadServlet';
config.extraPlugins = 'image2';
};
Upload Servlet:
public class CKEditorUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String ERROR_FILE_UPLOAD = "An error occurred to the file upload process.";
private static final String ERROR_NO_FILE_UPLOAD = "No file is present for upload process.";
private static final String ERROR_INVALID_CALLBACK = "Invalid callback.";
private static final String CKEDITOR_CONTENT_TYPE = "text/html; charset=UTF-8";
private static final String CKEDITOR_HEADER_NAME = "Cache-Control";
private static final String CKEDITOR_HEADER_VALUE = "no-cache";
private static final Pattern PATTERN = Pattern.compile("[\\w\\d]*");
private String errorMessage = "";
public CKEditorUploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CKEDITOR_CONTENT_TYPE);
response.setHeader(CKEDITOR_HEADER_NAME, CKEDITOR_HEADER_VALUE);
final FileItemFactory factory = new DiskFileItemFactory();
final ServletFileUpload upload = new ServletFileUpload(factory);
List fileItems = null;
Iterator itr = null;
FileItem fi = null;
File file = null;
String contentType = "";
byte[] content;
String id = UUID.randomUUID().toString().substring(0, 8);
System.out.println(id);
final PrintWriter out = response.getWriter();
UploadBean bean = (UploadBean) getServletContext().getAttribute("uploadBean");
if (bean == null) {
bean = new UploadBean();
getServletContext().setAttribute("uploadBean", bean);
}
try {
/*final List items = upload.parseRequest(request);
if (!items.isEmpty() && items.get(0) != null) {
System.out.println("Content "+((DiskFileItem) items.get(0)).get());
System.out.println("Content Type "+((DiskFileItem) items.get(0)).getContentType());
System.out.println("Name "+((DiskFileItem) items.get(0)).getName());
} else {
//No file to Upload
}*/
fileItems = upload.parseRequest(request);
itr = fileItems.iterator();
while ( itr.hasNext () )
{
fi = (FileItem)itr.next();
if ( !fi.isFormField () )
{
String fileName = fi.getName();
System.out.println("FileName "+fileName);
String ext = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
boolean isInMemory = fi.isInMemory();
contentType = fi.getContentType();
content = fi.get();
bean.setContent(fi.get());
long sizeInBytes = fi.getSize();
if( fileName.lastIndexOf("\\") >= 0 )
{
file = new File("D:\\Document" + "\\" + id + "." + ext) ;
}
else
{
file = new File("D:\\Document\\" + "\\" + id + "." + ext) ;
}
fi.write( file ) ;
}
}
bean.setId(id);
bean.setContentType(contentType);
} catch (Exception e) {
e.printStackTrace();
}
finally
{
fileItems = null;
itr = null;
fi = null;
}
// CKEditorFuncNum Is the location to display when the callback
// String callback = request.getParameter("CKEditorFuncNum");
String callback ="1";
System.out.println("Callback "+callback);
// verify if the callback contains only digits and letters in order to
// avoid vulnerability on parsing parameter
if (!PATTERN.matcher(callback).matches()) {
System.out.println("Patten not matches");
callback = "";
errorMessage = ERROR_INVALID_CALLBACK;
}
final String pathToFile = request.getContextPath()
+ "/CKEditorGetImageServlet?imageId=" + bean.getId();
System.out.println("Path to File "+pathToFile);
out.println("<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction("
+ callback + ",'" + pathToFile + "','" + errorMessage + "')");
out.println("// ]]></script>");
out.flush();
out.close();
}
}
GetImage Servlet
public class CKEditorGetImageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String ERROR_FILE_DOWNLOAD = "An error occured when trying to get the image with id:";
private static final String IMAGE_PARAMETER_NAME = "imageId";
private static final long CACHE_AGE_MILISECONDS_TWO_WEEKS = 1209600000;
private static final String CKEDITOR_CONTENT_EXPIRE = "Expires";
private static final String CKEDITOR_CONTENT_TYPE = "Content-Type";
private static final String CKEDITOR_CONTENT_LENGTH = "Content-Length";
private static final String CKEDITOR_CONTENT_DISPOSITION = "Content-Disposition";
private static final String CKEDITOR_CONTENT_DISPOSITION_VALUE = "inline; filename=\"";
private static final String CKEDITOR_HEADER_NAME = "Cache-Control";
public CKEditorGetImageServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
UploadBean bean = (UploadBean) getServletContext().getAttribute("uploadBean");
final byte[] rb = bean.getContent();
System.out.println("Inside get Image Servlet "+rb);
System.out.println("Content Type "+bean.getContentType());
final long expiry = new Date().getTime()
+ CACHE_AGE_MILISECONDS_TWO_WEEKS;
response.setDateHeader(CKEDITOR_CONTENT_EXPIRE, expiry);
response.setHeader(CKEDITOR_HEADER_NAME, "max-age="
+ CACHE_AGE_MILISECONDS_TWO_WEEKS);
response.setHeader(CKEDITOR_CONTENT_TYPE,
bean.getContentType());
response.setHeader(CKEDITOR_CONTENT_LENGTH,
String.valueOf(rb.length));
response.setHeader(
CKEDITOR_CONTENT_DISPOSITION,
CKEDITOR_CONTENT_DISPOSITION_VALUE
+ bean.getName() + "\"");
response.getOutputStream().write(rb, 0, rb.length);
response.getOutputStream().flush();
response.getOutputStream().close();
}
As per the Official Documentation of ckeditor we need to write the xhr code at editor level and also at server level which I am not able to get. Could you please help me out in achieving the same.

Unable to get data at first click in android webview with server communication

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));
}

Requesting to a servlet file downloading via ajax(no jquery please..)

The process is this:
from web(jsp) I upload some pdf file(submitting via ajax)
in the backend I merge these pdf
I get the response(the merged pdf) via ajax --> start the file download...
I'm having issues with the third step.
I've included only the relevant code where I submit the file to upload (post request) and start the download.
I put also a direct link, that calls the same steps in get method and works.
Where is my problem?
Thanks in advance...
Here is the jsp body tag
<a href="/TestAjaxServletDownload/DownloadServlet" >
download
</a>
<p><input id="sampleFile5" name="sampleFile5" type="file" /></p>
<p><input id="uploadBtn" type="button" value="Upload" onClick="javascript:performAjaxSubmit();"></input></p>
Here is my javascript tag content
function performAjaxSubmit() {
var sampleFile1 = document.getElementById("sampleFile5").files[0];
var formdata = new FormData();
formdata.append("sampleFile", sampleFile1);
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// alert("ok..." + xhr.responseText);
//?????????????????????????????
document.location=xhr.responseText;
}
};
xhr.open("POST","/TestAjaxServletDownload/DownloadServlet", true);
xhr.send(formdata);
}
Here is my web.xml servelet mapping tags
<servlet>
<description></description>
<display-name>DownloadServlet</display-name>
<servlet-name>DownloadServlet</servlet-name>
<servlet-class>test.DownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadServlet</servlet-name>
<url-pattern>/DownloadServlet</url-pattern>
</servlet-mapping>
Here is my servlet code
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("DO GET SERVLET MERGE");
execute (request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("DO POST SERVLET MERGE");
execute (request, response);
}
protected void execute(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
File downloadFile = new File("c:\\data\\example.pdf");
System.out.println("++++" + downloadFile.getAbsolutePath());
// System.out.println(uploadPathTemp+mergeFileName);
FileInputStream inStream = new FileInputStream(downloadFile);
// obtains ServletContext
ServletContext context = getServletContext();
// gets MIME type of the file
String mimeType = context.getMimeType(downloadFile.getCanonicalPath());
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
// modifies response
response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
// forces download
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
System.out.println(downloadFile.getName());
response.setHeader(headerKey, headerValue);
// obtains response's output stream
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inStream.close();
outStream.close();
}
What about changing
<a href="/TestAjaxServletDownload/DownloadServlet" >
download
</a>
to
<a id="pdfLink" href="/TestAjaxServletDownload/DownloadServlet" >
download
</a>
and then use document.getElementById('pdfLink').click()?

servlet - Why is the XMLHttpRequest responseText always blank?

I am losing my mind trying to solve this problem over here. I have the following servlet deployed in Tomcat running on localhost:8080-:
#WebServlet(urlPatterns = { "/createcon" }, asyncSupported = true)
public class CreateCon extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
ConcurrentHashMap<String, AsyncContext> map;
public CreateCon() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public void init() {
map = new ConcurrentHashMap<>();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext context = request.startAsync(request,response);
context.setTimeout(10000);
if(!map.containsKey("Hello"))
map.put("Hello", context);
System.out.print("Inside GET");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext context = map.get("Hello");
PrintWriter writer = context.getResponse().getWriter();
writer.write(request.getParameter("message"));
writer.flush();
System.out.print(request.getParameter("message"));
}
}
As you can see I am trying to store an AsyncContext that is created in Map. I code runs fine in Eclipse with Tomcat. As you can see above that I have added System.out.print to actually check whether the code is working properly or not. And it works exactly as expected.
But the problem is with the javascript below-:
function postMessage(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText);
}
}
xmlhttp.open("POST", "/SampleTest/createcon", true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var messageText = escape(document.getElementById("i1").value);
document.getElementById("i1").value = "";
xmlhttp.send("message="+messageText);
}
The onreadystatechange fires exactly when expected but the xmlhttp.responseText is always blank.
I know that there is something known as a same-origin policy. But I don't understand why that's a problem here ? I am running everything on localhost:8080.
Why is this still happening and how do I solve this ?
Okay solved it. Guess it was my own silly mistake. The startchat() method should be modified like-:
function startChat() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "/SampleTest/createcon", true);
xmlhttp.send();
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText);
}
}
}
Since I am trying to find the result from the request made at startChat().

Categories