I have a script in which on Click on link i need to download PDF file present in temp folder on server and this i am doing it by calling AJAX function. that AJAX function is calling struts 2 action method which is reading content of the file and write it to output stream.
and now problem is if that file is not present in temp folder. that is throwing exception. so i decided to handle it by using json. if that file exist in temp folder. i am mapping the key to
jsonObject.put("exist", true)
and if that file does not exist in temp folder. i am mapping the key to
jsonObject.put("exist", false)
and in struts.xml i am handling the action by with this way
<action name="DisplayStaticPdf"
class="com.ui.DisplayStaticPdfAction">
<result name="success" type="json"/>
</action>
and in script i am handling it through this way
function downloadDoc(actionName){
$.ajax({
url: actionName,
type: 'post',
dataType: 'json',
error: function(data) {
if(data.exist!= null && data.exist == 'false'){
alert('The document you are trying to download does not exist at location. Please make sure file exist .');
}
},
success: function() {
}
});
}
and when file is not present, it is showing me the same alert. but when file is not present, it does nothing and does not download the pdf present in temp folder.
my action class looks like ->
String pdfFileName = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
String rawFileName = "abc.pdf";
String returnString = "fileNotExist";
jsonObject = new JSONObject();
ServletOutputStream out = response.getOutputStream();
response.setContentType("application/pdf");
URL url = new URL(fileURL);
URLConnection conn = url.openConnection();
if (conn.getContentLength() != 0 && conn.getContentLength() != -1)
{
bis = new BufferedInputStream(conn.getInputStream());
bos = new BufferedOutputStream(out);
try
{
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
{
bos.write(buff, 0, bytesRead);
}
jsonObject.put("exist", true);
}
returnString = SUCCESS;
}
else
{
jsonObject.put("exist", false);
returnString ="fileNotExist";
}
return returnString;
hope you guys understand my issue. Anybody please put light on this whether i am doing it in right approach. or is there is any other easy way to do it
Thanks,
Ankit
Related
I am developing a login function by passing json object to servlet for validation. If the login/password match with DB. The page will redirect to a main page with the login ID and corresponding profile. Or redirect to an error page if login fail. Here my coding:
jsp:
function submitForm(thisObj, thisEvent) {
var sLogin = $('#userName').val();
var sPwd = $('#userPwd').val();
var myData = {
"userName": sLogin,
"userPwd": sPwd
};
$.ajax({
type: "POST",
url: "login",
data: JSON.stringify(myData),
dataType: "json",
success: function(result){
if (result.status == "SUCCESS"){
setAttribute("ID", result.requestId);
}
}
});
return false;
}
servlet:
public class login extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
res.setContentType("application/json");
PrintWriter out = res.getWriter();
StringBuffer sbuffer = new StringBuffer();
String inLine = null;
String sUsername = "", sUserPwd = "";
try{
BufferedReader reader = req.getReader();
while ((inLine = reader.readLine()) != null)
sbuffer.append(inLine);
if (sbuffer.length() != 0){
JSONObject jsObj = new JSONObject(sbuffer.toString());
sUsername = jsObj.optString("userName");
sUserPwd = jsObj.optString("userPwd");
}
}catch(Exception e){
out.print("error");
return;
}
if (sUsername == "userA") {
JSONObject jsonSResp = new JSONObject();
jsonResp.put("status", "SUCCESS");
jsonResp.put("requestId", "1");
jsonResp.put("url", "LoginOK.jsp");
out.println(jsonResp.toString());
}
}
The servlet can get the user input login/password and perform validation. And return result back to ajax. Up next, i want to pass the data from ajax success function to new page by using set session.setAttribute() method but not works. Can anyone give hint to me to solve such problem? Thanks.
I think you need to use "rd.forward(req, res);" intead of "rd.include(req, res);" in this case.
actually, i just want to return a success page with user profile (as json object) for follow up action if login/password match with mysql database or return login fail page for invalid login. but i really don't have any idea what my coding wrong.
I have create a json file config.json and a json exteded class to manager this json file.
Basically I'd like to read and update this file.
To read:
init : function(fnSuccess, scope) {
this.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay);
this.loadData("conf.json");
this.attachRequestCompleted(function() {
window.url = this.getProperty("/config/url");
window.port = this.getProperty("/config/port");
window.ldap = this.getProperty("/config/ldap");
if(typeof fnSuccess === 'function')
fnSuccess(scope);
});
},
It worked fine!
Now, to update the file:
save: function(url, port, ldap){
if(url != null)
this.setProperty("/config/url", url);
if(port != null)
this.setProperty("/config/port", port);
if(ldap != null)
this.setProperty("/config/ldap", ldap);
console.log(this.getJSON());
}
The console.log(this.getJSON()) print my changed JSON model, but when I reload or open the conf.json file, nothing was changed!
Is it possible to do that?
Thanks.
In my site, i gave download option to download the file. when i am checking in local server it is working properly. But after deploy the server, if i click the link means it will show the following error,
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
My code here
public ActionResult Download(string fileName)
{
string pfn = Server.MapPath("~/Content/Files/" + fileName);
if (!System.IO.File.Exists(pfn))
{
//throw new ArgumentException("Invalid file name or file not exists!");
return Json(new JsonActionResult { Success = false, Message = "Invalid file name or file not exists!" });
}
else
{
return new BinaryContentResult()
{
FileName = fileName,
ContentType = "application/octet-stream",
Content = System.IO.File.ReadAllBytes(pfn)
};
}
}
This is my code. I don't know what mistake here, Can anyone find my problem and tell me ?
The Problem with ur code is that u r missing 'JsonRequestBehavior.AllowGet' while returning json.
public ActionResult Download(string fileName)
{
string pfn = Server.MapPath("~/Content/Files/" + fileName);
if (!System.IO.File.Exists(pfn))
{
//throw new ArgumentException("Invalid file name or file not exists!");
return Json(new JsonActionResult { Success = false, Message = "Invalid file name or file not exists!" },JsonRequestBehavior.AllowGet });
}
else
{
return new BinaryContentResult()
{
FileName = fileName,
ContentType = "application/octet-stream",
Content = System.IO.File.ReadAllBytes(pfn)
};
}
}
I want upload a file (any type) on a server.
I have my file which is saved like this (I use FileAssociation)
await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "fileToSave" + fileext, NameCollisionOption.ReplaceExisting, NavigationContext.QueryString["filetoken"]);
Then I get the saved file
StorageFolder folder = ApplicationData.Current.LocalFolder;
var file = await folder.GetFileAsync("fileToSave" + fileext);
Stream data = Application.GetResourceStream(new Uri(file.Path, UriKind.Relative)).Stream;
string filename = System.IO.Path.GetFileName(file.Path);
ServerFunctions.UploadFile(filename,data);
Then I start the Upload
internal void UploadFile(string fileName,Stream data)
{
WebClient web = new WebClient();
if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin))
{
System.Net.NetworkCredential account = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword);
web.Credentials = account;
}
web.AllowReadStreamBuffering = true;
web.AllowWriteStreamBuffering = true;
web.OpenWriteCompleted += (sender, e) =>
{
PushData(data, e.Result);
e.Result.Close();
data.Close();
};
web.OpenWriteAsync(dataRequestParam.TargetUri,"POST");
}
private void PushData(Stream input, Stream output)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
{
output.Write(buffer, 0, bytesRead);
}
}
The web server is supposed to send me as a response a xml with an error code or succes code inside.
None error is thrown but it doesnt work.And I don't understand why the e.result is a stream object. As I said the server should return a string...(xml file)
Could you bring me some explannations of what is happening in my code and if it will work with all types of files ?
Thanks
I think part of the problem here is that you're attempting to get this to behave like a streaming protocol when it seems you intend a request/response type architecture. For those purposes, you should consider working with a WebRequest object.
Bear with me as I fully qualify the namespace of the objects used inline, so it may get a little verbose, but I want you to know where to find these things.
internal async void UploadFile(string fileName, System.IO.Stream data)
{
// Specify URI, method, and credentials for the request
System.Net.WebRequest web = System.Net.HttpWebRequest.CreateHttp(dataRequestParam.TargetUri);
web.Method = "POST";
if (!string.IsNullOrEmpty(dataRequestParam.AuthenticationLogin))
{
web.Credentials = new System.Net.NetworkCredential(dataRequestParam.AuthenticationLogin, dataRequestParam.AuthenticationPassword);
}
// Create the request payload from the provided stream
System.IO.Stream requestStream =
await System.Threading.Tasks.Task<System.IO.Stream>.Factory.FromAsync(web.BeginGetRequestStream, web.EndGetRequestStream, null);
await data.CopyToAsync(requestStream);
// Get a response from the server
System.Net.WebResponse response =
await System.Threading.Tasks.Task<System.Net.WebResponse>.Factory.FromAsync(web.BeginGetResponse, web.EndGetResponse, null);
// Possibly parse the response with an XmlReader (example only)
System.Xml.XmlReader reader = System.Xml.XmlReader.Create(response.GetResponseStream());
string responseText = reader.ReadInnerXml(); // TODO: Real work here
}
The one oddity here is using the Task factory to create a task from the begin and end methods from getting both the request stream and the response. This makes it much simpler to consume these methods as you get a Task back which can be awaited for its return object, which you can then manipulate directly.
I'm not sure what form your response from the server takes on success versus failure, so I've simply shown how to create an XML reader to parse XML from the resulting stream. You can do whatever parsing is necessary yourself on these lines, but this should at least give you a look at what your server is returning in response.
The final code I use.
WebRequest web = HttpWebRequest.CreateHttp(dataRequestParam.TargetUri);
web.ContentType = dataRequestParam.ContentType;
web.Method = "POST";
web.ContentLength = data.Length;
if (!string.IsNullOrEmpty(dataRequestParam.AuthentificationLogin))
{
web.Credentials = new NetworkCredential(dataRequestParam.AuthentificationLogin, dataRequestParam.AuthentificationPassword);
}
using (var requestStream = await Task<Stream>.Factory.FromAsync(web.BeginGetRequestStream, web.EndGetRequestStream, web))
{
await data.CopyToAsync(requestStream);
}
WebResponse responseObject = await Task<WebResponse>.Factory.FromAsync(web.BeginGetResponse, web.EndGetResponse, web);
var responseStream = responseObject.GetResponseStream();
var sr = new StreamReader(responseStream);
string received = await sr.ReadToEndAsync();
return received;
}
Specification:
Server 2012
Framework 3.5
I have already deployed my webservice in the server http://ipaddress/eSignatureWS.asmx?op=SaveImg.
Problem: when i change the ajax dataType to "json" or "text" it has an Internal Server Error, but when i used "script" it won't have an error but it don't save the image. When i try it locally it works using "json"/"text" but when i deployed it won't work anymore.
So here's my code:
Jquery
function signatureSave() {
var canvas = document.getElementById("newSignature"); // save canvas image as data url (png format by default)
var data = canvas.toDataURL("image/png");
var signatureData = data.replace(/^data:image\/(png|jpg);base64,/, "");
var donum = "sampleImg"; //imagename
$.support.cors = true;
//var imgData = JSON.stringify(signatureData);
$.ajax({
type: "Post",
async: false,
url: "http://ipaddress/eSignatureWS.asmx?op=SaveImg",
data: { "filename": donum, "imgBit": signatureData },
dataType: "json",
success: function (data) { //alert(data);
if (data.match("true")) {
document.getElementById('errorImage').innerHTML = "Successfully Submitted!";
}
else {
document.getElementById('errorImage').innerHTML = "Error occured.";
}
},
error: function (XMLHttpRequest, testStatus, errorThrown) {
document.getElementById('errorImage').innerHTML = errorThrown;
alert(XMLHttpRequest + testStatus + errorThrown);
}
})
Webservice
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string SaveImg(string filename, string imgBit)
{
try
{
string filepath = WebConfigurationManager.AppSettings["ImgLocation"].ToString();
string imgPath = filepath + filename + ".png";
//creates a png image signature
using (FileStream fs = new FileStream(imgPath, FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
byte[] data = Convert.FromBase64String(imgBit);
bw.Write(data);
bw.Close();
JavaScriptSerializer js = new JavaScriptSerializer();
string strJSON = js.Serialize("true");
return strJSON;
}
}
}
catch (Exception ex)
{
}
}
Check the edit section!
I'm guessing you're not aware of the "maxJsonLength" attribute which is set to 100KB by default, in ASP.NET. I wasn't aware of that till the latest search I had to make about the same subject :)
In the Web.Config file you can change this default limitation to your needs.
<configuration>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="1000000"/>
</webServices>
</scripting>
</system.web.extensions>
</configuration>
That one is 1.000.000 bytes which is ~1MB. You can set higher values if you need to send bigger files through your webservice.
Check that and please let me know if it works.
EDIT: I recently found out that this is not the only setting you should make. You should also set the "maxRequestLength" attribute of the httpruntime node in web.config file, like:
<system.web>
<httpRuntime targetFramework="4.5" maxRequestLength="10000" executionTimeout="10800" />
</system.web>
Here, maxRequestLength is in KBs, so 10000 means ~10MBs (9,77MB exactly). If users have low bandwidths and your requestlength requirement is bigger than 10MB, then you can set executionTimeout attribute to a higher value. That is in seconds, so 10800 means 3 hours.
I think you got the picture here.
Cheers!