I am using Spring MVC, Following is a method which will take either String or Input Stream from the Request and convert into PDF and write the PDF to the respose.
public void generatePDF(RequestDTO requestUIDTO, Map<String, Object> responseMap,
HttpServletRequest request, HttpSession session, HttpServletResponse response) {
Document document = new Document();
PdfWriter writer;
try {
writer = PdfWriter.getInstance(document, response.getOutputStream());
document.open();
//Here I need to get the HTML file as String or InputStream from the request.
//For now i am getting InputStream, It may be string
InputStream in = request.getInputStream();
XMLWorkerHelper.getInstance().parseXHtml(writer, document, in);
document.close();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Now the problem is, I don't know how to send the current rendered page as HTML to the server, I tried the following Java script but it is not working, the request itself is not going to the server May be because i am sending a huge file as request parameter.
function downloadLoanForm(){
var params = {};
params = {
htmlContent : "htmlContent"
}
handleRequest(this, params, 'generatePDF.htm', '');
}
$(document).ready(function(){
var htmlContent = $('#mainFormId').html();
$('#htmlContent').val(htmlContent);
});
My Question is this, Please let me know a way to send the current rendered HTML code to the Server as either a String (or) Stream.
Here is the Java script code for handleRequest() function,
function handleRequest(obj, params, request_url, replacement_element_id,
error_redirection, function_call_after_response) {
//check if there is any value present for the request url
if(!request_url)
{
alert('<spring:message code="JS_MSG_PROVIDE_URL_FOR_REQUEST" text=""/>');
return false;
}
//check if the url is an external url
if(isExternal(request_url) === true)
{
alert('<spring:message code="JS_MSG_REQUEST_CANNOT_SENT_TO_EXTERNAL_LINK" text=""/>');
return false;
}
//global variable for making the decision on the page redirect after the error from the server - default value is false
error_redirection = error_redirection || false;
//variable containing the replacement element id which will be used to place the content after the response from the server
replacement_element_id = replacement_element_id || false;
//variable to decide whether some manipulation has to be done on the response data from the server
// the response data is being sent to this function along with the replacement element id
function_call_after_response = function_call_after_response || '';
//alert(function_call_after_response+'-here');
//set the replacement element's html values to to be empty before the request is being made so as to ensure that user does not go forward without getting the correct result
if(replacement_element_id)
{
$('#'+replacement_element_id).html("");
}
//var serializedData = Array();
var counter = 0;
//SETTING THE REQUIRED ELEMENTS VALUES TO AN JSON OBJECT FOR SENDING TO THE SERVER - the elements required for the post is passed as an array in the arguments
var serializedData = {};
$.each(params, function(key, field) {
if($("#"+key).length > 0) {
//field = escapeHtml(field);
var value = $("#"+key).val();
/*if($('input[name="'+field+'"]').length > 0)
{
value = $('input[name="'+field+'"]').val();
}
else if($('select[name="'+field+'"]').length > 0)
{
value = $('select[name="'+field+'"]').val();
}
else if($('textarea[name="'+field+'"]').length > 0)
{
value = $('textarea[name="'+field+'"]').val();
}*/
value = escapeHtml(value);
if(value != "")
{
counter++;
}
//serializedData.field = value;
serializedData[field] = value;
/*
if(counter == 0)
{
serializedData = field+'='+value;
}
else
{
serializedData += '&'+field+'='+value;
}
counter++;
*/
}
});
if(counter == 0)
{
return false;
}
serializedData.csrfToken = $('form > input[name=csrfToken]').val();
//alert($('form > input[name=csrfToken]').val());
if(isExternal(request_url) === false)
{
$('input[name="'+$(obj).attr('name')+'"]').css('float', 'left');
$.blockUI({ message: "<h3><img src='images/processing.gif' id='processing_plz_wait' alt='Processing...' title='Processing...' border='0' class='processing_img' /><br/><spring:message code="JS_MSG_PLEASE_WAIT" text=""/></h3>" });
$(".blockOverlay").show();
$(".blockOverlay").css("opacity", "0.6");
$(".blockMsg").show();
$(".blockMsg").css("opacity", "1");
//setTimeout(function() {
$.ajax({
type: "POST",
url: request_url,
data: serializedData,
success: function(data, status, xhr) {
if(data) {
//check for some strings to validate session time out - TODO need proper validation check
if(data.contains("<html>") && data.contains("<head>")){
document.location.href = 'logout.htm';
} else {
if(replacement_element_id === false) {
alert('<spring:message code="JS_MSG_OPERATION_PERFORMED_SUCCESSFULLY" text=""/>');
return false;
}
else {
//set the response from the server to the form display element
$('#'+replacement_element_id).html(data);
setTokenValFrmAjaxResp();
$('#'+replacement_element_id).find("form ").append('<input type="hidden" value="'+$('#csrfToken').val()+'" name="csrfToken">');
$('form > input[name=csrfToken]').val($('#csrfToken').val());
if(function_call_after_response != "")
{
eval(function_call_after_response);
}
return false;
}
}
}
},
//ERROR HANDLING AS PER THE RESPONSE FROM THE SERVER - TO DO (some extra layer of error handling to be done)
error: function(jqXHR, exception) {
if (jqXHR.status === 0) {
alert('<spring:message code="JS_MSG_NOT_ABLE_TO_CONNECT_VERIFY_NETWORK" text=""/>');
} else if (jqXHR.status == 404) {
alert('<spring:message code="JS_MSG_REQUEST_PAGE_NOT_FOUND" text=""/>');
} else if (jqXHR.status == 500) {
alert('<spring:message code="JS_MSG_INTERNAL_SERVER_ERROR" text=""/>');
} else if (exception === 'parsererror') {
alert('<spring:message code="JS_MSG_REQUESTED_DATA_PARSE_FAILED" text=""/>');
} else if (exception === 'timeout') {
alert('<spring:message code="JS_MSG_TOME_OUT_ERROR" text=""/>');
} else if (exception === 'abort') {
alert('<spring:message code="JS_MSG_AJAX_REQUEST_ABORTED" text=""/>');
} else {
alert('<spring:message code="JS_MSG_UNCAUGHT_ERROR" text=""/>' + jqXHR.responseText);
if(error_redirection === true)
{
//redirect to the corresponding error page
document.location.href = '';
}
}
setTokenValFrmAjaxResp();
return false;
}
});
//}, 100);
}
}
Related
Am throwing exception from my servlet and in the eclipse console its printing the exception logs whenever exception is occured. But am trying to show that exception in JSP pages that am not getting.
Please find my code below.
code to pass the request :
function sendRequest( functionCallback, servletLocation, queryString)
{
var asyncRequest = newXMLRequest();
// Set the handler function to receive callback notifications from the request object
var handleResponse = getReadyStateHandler(asyncRequest, functionCallback);
asyncRequest.onreadystatechange = handleResponse;
// Send a POST to servlet for information. Third parameter specifies request is asynchronous.
asyncRequest.open("POST", servletLocation, true);
asyncRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
asyncRequest.send(queryString);
if ( document.getElementById("filterMessage") != null )
{
document.getElementById("filterMessage").innerHTML = "<span class = 'red'>Filtering...Please Wait</span>";
}
}
code to handle the respose :
function getReadyStateHandler(req, responseXmlHandler)
{
// Return an anonymous function that listens to the
// XMLHttpRequest instance
return function ()
{
// If the request's status is "complete"
if (req.readyState == 4)
{
// Check that a successful server response was received
if (req.status == 200)
{
// Pass the XML payload of the response to the
// handler function
responseXmlHandler(req.responseXML);
}
else
{
// An HTTP problem has occurred
alert("HTTP error: " + req.status);
}
}
}
}
function reloadPage() {
window.location.reload(true);
}
invoking servlet call from the below code.
function updateProgramVersion(e) {
var washoutIdStr = (e.target || e.srcElement ).parentNode.parentNode.parentNode.children.sparWashoutId.children.washoutItem.value;
var programVersionStr = (e.target || e.srcElement ).parentNode.parentNode.parentNode.children.programVersionModify.children.programVersion.value;
var sparNumber = (e.target || e.srcElement ).parentNode.parentNode.parentNode.children.sparNumber.children.sparNumber.value
if( (e.target || e.srcElement ).id == 'programVersionUpdatebtn') {
query = 'actionId=updateProgramVersion&washoutIdStr='+washoutIdStr+"&programVersion="+ programVersionStr+"&sparNumber="+sparNumber;
servlet = "<%=UrlBuilder.getServletRoot() + ApplicationConstants.SERVLET_REPORT_SPAR%>"; method="POST";
sendRequest(reloadPage, servlet, query); // servlet call
(e.target || e.srcElement ).parentNode.parentNode.parentNode.children.programVersion.style.display = 'none';
(e.target || e.srcElement ).parentNode.parentNode.parentNode.children.programVersionTD.style.display = 'block';
}
}
Please find my below servlet code :
else if(actionId.equals("updateProgramVersion")) {
updateProgramVersion(washoutId, sparNumber, programVersion);
//nextPage = mappings.findForward("display");
}
private void updateProgramVersion(String washoutId, String sparNumber, String programVersion) throws ApplicationException{
boolean isExist = sparwashoutService.getProgramVersion(washoutId, sparNumber, programVersion);
if(isExist) {
sparwashoutService.updateProgramVersion(washoutId, sparNumber, programVersion);
} else {
throw new InvalidInputException("Version number is not valid","Version number is not valid",this.getClass().toString().substring( getClass().toString().lastIndexOf(".") + 1 ) + ".performTask()");
}
}
You need to send back custom message which you need to show in jsp via servlet using response.getWriter().write().. also you can set status so that it will not enter inside if (req.status == 200) {... Here is example with try-catch block modify below code according to your requirement .
Servlet Code :
try
{
//check some condition
response.setContentType ("text/xml");
response.setCharacterEncoding ("UTF-8");
response.setStatus(200); //set status
response.getWriter().write(yourxmldata); //send message
}
//handling the exception
catch (Exception e)
{
response.setContentType ("text/plain");//set contenttype to text
response.setCharacterEncoding ("UTF-8");
response.setStatus(406); //set status
response.getWriter().write (e.getMessage () + "I AM IN EXECPETION"); //get your execption message
}
and in Ajax just check the status code :
if (req.status == 200) {
responseXmlHandler(req.responseXML);//xml return
} else if(req.status == 406){
alert(req.responseText);//text return
}
I perform an edit to ensure against duplicate emails by making an ajax call and supplying a callback. If a duplicate exists, I want to return false from submit event. Is there an elegant way to achieve this without setting async=false? What I tried (see emailCallback) is not working.
submit event
EDIT (included the rest of the submit handler).
$("#form-accounts").on("submit", function (e) {
e.preventDefault();
if (!$(this).get(0).checkValidity()) return false;
if (!customValidation(true, false)) return;
checkDupEmail(emailCallback);
function emailCallback(result) {
if (result) return (function () { return false } ());
}
if ($("#submit").text() == "Create Account") {
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/accounts.php', formData + "&action=create-account", createSuccess);
function createSuccess(result) {
if (isNaN(result)) {
showMessage(0, result);
return;
}
localStorage.setItem("account-id", result);
debugger
setUsertype($("input[name=user-type]:checked").val());
showMessage(1, "Account Created");
};
return
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
};
var anRandom = randomString(14, rString);
$("#code").val(anRandom);
console.log("v-code=" + anRandom);
$("#submit").css({ 'display': 'none' });
$("#verify").css({ 'display': 'block' });
var subject = "Writer's Tryst Verification Code"
$("#subject").val(subject);
var msg = "This mail is intended for the person who requested verification of email ownership at Writers-Tryst (" + getWriterTrystURL() + ").\n\n" + "Double click on the code below and then copy it. Return to our website and and paste the code.\n\nYour verification code: \n\n" + anRandom;
$("#msg").val(msg);
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/sendmail.php', formData, successMail, "create-account error: ");
function successMail(result) {
$("#ver-email-msg").val("An email has been sent to you. Double-click the verification code then copy and paste it below.").css({ 'display': 'block' });
}
});
function checkDupEmail(callback) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, emailSuccess);
function emailSuccess(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
callback(true);
} else callback(false);
}
}
Instead of passing a callback, why don't you just submit the form when your Ajax call completes successfully?
$("#form-accounts").on("submit", function (e) {
// Always cancel the submit initially so the form is not submitted until after the Ajax call is complete
e.preventDefault();
...
checkDupEmail(this);
...
});
function checkDupEmail(form) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, function(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
} else {
form.submit();
}
}
}
A better approach than that would be to submit your form using Ajax. That would eliminate the need for two calls to the server.
On a form submit I am calling following function.
function confirmSubmit() {
var checkedAtLeastOne = false;
var checkboxs = document.getElementsByName("reportColumns");
var reportId = $('#reportId').val();
console.log(checkboxs.length);
for(var i = 0, l = checkboxs.length; i < l; i++) {
if(checkboxs[i].checked) {
checkedAtLeastOne = true;
break;
}
}
if(checkedAtLeastOne) {
if(!reportId) {
alert('Report ID cannot be empty');
return false;
} else {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "checkreportid.action?reportId=" + reportId, true);
xhttp.send();
xhttp.onreadystatechange = function (e) {
if(xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("checkreportid").innerHTML = xhttp.responseText;
var reportid = $('#reportid').val();
console.log("reportId->" + reportId);
console.log("reportid->" + $('#reportid').val());
if(reportid == reportId) {
alert("Duplicate Report ID!");
return false;
} else {
return true;
}
}
}
}
} else {
alert("You must select atleast one column");
//e.preventDefault();
return false;
}
}
Here if the reportid equals to reportId it gives the alert (Duplicate Report ID) but it calls the action. return false is not prevent calling the action.
I am calling the function as below.
<s:form action="savereport" namespace="/" validate="true"
onsubmit="return confirmSubmit()">
EDITED
Now I am trying following. If the report ID is empty it gives relevant alert message (Report ID cannot be empty). It it is not empty it calls the checkreportid action but it doesn't give duplicate error message even if there are duplicate report ids. It calls the form submitting action.
function confirmSubmit() {
var checkedAtLeastOne = false;
var checkboxs = document.getElementsByName("reportColumns");
var reportId = $('#reportId').val();
console.log(checkboxs.length);
for (var i = 0, l = checkboxs.length; i < l; i++) {
if (checkboxs[i].checked) {
checkedAtLeastOne = true;
break;
}
}
if (!reportId) {
alert('Report ID cannot be empty');
return false;
} else {
////////
$.ajax({
url: "<s:url action='checkreportid'/>",
type: "GET",
data: {reportId: reportId},
dataType: "text/javascript",
traditional: true,
statusCode: {
200: function (data) {
console.log(data.responseText);
document.getElementById("checkreportid").innerHTML = data.responseText;
var reportid = $('#reportid').val();
console.log("reportId->"+reportId);
console.log("reportid->"+reportid);
if (reportid==reportId) {
alert("Duplicate Report ID!");
return false;
} else {
if (!checkedAtLeastOne) {
return true;
} else {
alert("You must select atleast one column");
return false;
}
}
}
}
});
}
}
What am I missing with my code ?
This is due to the asyncronous nature of a XMLHttpRequest. You are returning false in a callback function, not in the onsubmit handler.
You should look into doing what you want without an XMLHttpRequest or use a syncronous request (this is not reccomended and disabled in some browsers).
The reccomended option is to stop the form submitting all the time with
e.preventDefault();
return false;
And to manually submit the form with a XMLHttpRequest in the original callback if you want to.
The reason is that XMLHttpRequest is aysnchronous.
Your call to
xhttp.send();
returns immediately and therefore that if-else branch doesn't have a return false.
The return statements in your code boil down to:
if(checkedAtLeastOne) {
if(!reportId) {
return false;
} else {
}
} else {
return false;
}
You should add preventDefault method to the form element like below.
<form onsubmit='event.preventDefault(); return confirmSubmit();'>
<input type='submit' />
</form>
Use return in onsubmit event to trigger return false action,
<form onsubmit = "return confirmSubmit()">
</form>
I have a JS function which is sending request twice to action class. I am not sure where should I modify it to resolve the issue.
Below is the JS function.The problem is in ELSE part of it where I am checking runNoEmail==1 && runEmail==0
I am providing full JS function for better understanding
function runReportCheck(obj){
obj = window.event.srcElement;
if(runEmail==1 && runNoEmail==0)
{
openPopupWindow('popupType:Working');
runEmail=0;
var opt = {
method: 'post',
parameters: $('formLicStrands').serialize(true),
onSuccess: function(t) {
destroyPopupWindow();
if(t.responseText=="-2"){
openPopupWindow('title:Error; message: Conflict report is already being run.Please try again later.; popupType: Error; button1Value: OK; topRightClose: false',obj);
return;
}else
if(t.responseText=="-3"){
openPopupWindow('title:Warning; message: The conflict report will run and save in the background.An email will be sent to you upon completion.; popupType: Warning; button1Value: OK; topRightClose: false',obj);
return;
}
else
{ openPopupWindow('title:Run And Email Issue Report; URL:<c:url value="/secure/deal/conflict/newReport.dooo?"/>;formToSubmit:formLicStrands;topRightClose: false;onTitleBarCloseFunction:onConflictReportClose(<c:out value="${DEAL_BRIEF.ventanaId}"/>)',obj);
}
return;
},
onFailure: function(t) {
alert('Error ' + t.status + ' -- ' + t.responseText);
}
}
new Ajax.Request("<%=request.getContextPath()%>/secure/deal/conflict/newReport.dooo?isRunEmailClicked=true",opt);
return false;
}
else if(runNoEmail==1 && runEmail==0)
{
openPopupWindow('popupType:Working');
runNoEmail=0;
var opt = {
method: 'post',
parameters: $('formLicStrands').serialize(true),
onSuccess: function(t) {
destroyPopupWindow();
if(t.responseText=="-11"){
openPopupWindow('title:Error; message: Conflict report is already being run.Please try again later.; popupType: Error; button1Value: OK; topRightClose: false',obj);
return;
}
else
{
openPopupWindow('title:Run Issue Report; URL:<c:url value="/secure/deal/conflict/newReport.dooo?"/>;formToSubmit:formLicStrands;topRightClose: false;onTitleBarCloseFunction:onConflictReportClose(<c:out value="${DEAL_BRIEF.ventanaId}"/>)',obj);
}
return;
},
onFailure: function(t) {
alert('Error ' + t.status + ' -- ' + t.responseText);
}
}
new Ajax.Request("<%=request.getContextPath()%>/secure/deal/conflict/newReport.dooo",opt);
return false;
}else {
openPopupWindow('title:Run Issue Report; URL:<c:url value="/secure/deal/conflict/newReport.dooo?"/>;formToSubmit:formLicStrands;topRightClose: false;onTitleBarCloseFunction:onConflictReportClose(<c:out value="${DEAL_BRIEF.ventanaId}"/>)',obj);
}
return;}
When document ready i have set
$.ajaxSetup({
"error": function (XMLHttpRequest, textStatus, errorThrown) {
if(XMLHttpRequest.status == 403) {
display_modal( 'Please login to continue.', 'Session in closed.');
//XMLHttpRequest.abort();
}
}
});
to prevent ajax request from unauthenticated users.
but in a specific view, when a POST/GET request is made I have
var posting = $.post(
post_url,
$("#" + form).serialize(),
function(data) {
packet = data;
},
'json'
);
posting.done(function() {
form_post_response_function(e, packet);
});
posting.fail(function() {
var packet = {};
packet.data = {};
packet.data.type = "Ajax Post Fail";
packet.status = -200;
packet.statusMessage = "ERROR";
form_post_response_function(e, packet);
});
I was expecting to posting.fail(function() { and getting.fail(function() { not be called. But they are, so all the flow goes and it ends with another modal overlaping the 403 message.
How can I avoid this without raw $.ajax ? How stop JQuery flow at the error catch?
FINAL code
posting.fail(function(jqXHR, textStatus, errorThrown) {
if(jqXHR.status != 403) {
var packet = {};
packet.data = {};
packet.data.type = "Ajax Post Fail";
packet.status = -200;
packet.statusMessage = "ERROR";
form_post_response_function(e, packet);
} else {
// event also can be accessed here
$(get_target(e)).button('reset');
}
});
and it stop gently. looks good.
Throw an exception to stop the execution of further code.
For example: throw "stop execution here";
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
See que Question for all the details
This is the final code
posting.fail(function(jqXHR, textStatus, errorThrown) {
if(jqXHR.status != 403) {
var packet = {};
packet.data = {};
packet.data.type = "Ajax Post Fail";
packet.status = -200;
packet.statusMessage = "ERROR";
form_post_response_function(e, packet);
} else {
// event also can be accessed here
$(get_target(e)).button('reset');
}
});