I am using html,ajax and struts 2 to show image on UI. I am returning response as a byte[] of image from action and when I attach it with the image source then it shows some garbled values.
ajax call I am making from script is
$.ajax({
type: "POST",
url:url,
contentType: "image/png",
success: function(data){
$('.logo').html('<img src="data:image/png;base64,' + data + '" />');
}
} );
and action from where I am returning array of image byte is like this
public void execute(ActionInvocation invocation) throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType(action.getCustomContentType());
response.getOutputStream().write(action.getCustomImageInBytes());
}
public byte[] getCustomImageInBytes() {
System.out.println("imageId" + imageId);
BufferedImage originalImage;
try {
originalImage = ImageIO.read(getImageFile("C:\\temp\\Desert.jpg"));
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "png", baos);
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageInByte;
}
I've recreated your problem. It does appear to be the base64 encoding, although it works fine in the eclipse local preview without.
Use these two lines instead of response.getOutpuStream().write(...)
String encoded = javax.xml.bind.DatatypeConverter
.printBase64Binary(action.getCustomImageInBytes());
response.getOutputStream().print(encoded);
My full solution:
HTML
<!DOCTYPE html>
<html>
<head>
<title>Dynamic image test - stackoverflow issue 13946908</title>
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
</head>
<script>
$(document).ready(function() {
$.ajax({
type : "GET",
url : "/Test/ImageServer",
contentType : "image/png",
success : function(data) {
$('.logo').html('<img src="data:image/png;base64,' + data + '" />');
}
});
});
</script>
<body>
<div class="logo"></div>
</body>
</html>
Servlet
public class ImageServer extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("image/jpeg");
byte[] data = getCustomImageInBytes(request.getServletContext()
.getResource("/horse.jpg"));
String encoded = DatatypeConverter.printBase64Binary(data);
response.getOutputStream().print(encoded);
}
private byte[] getCustomImageInBytes(URL url) throws IOException {
BufferedImage originalImage = ImageIO.read(url);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
return imageInByte;
}
}
Tested
Chrome Version 23.0.1271.97 OSX 10.7.5
Firefox 16.0.2 OSX 10.7.5
Safari 6.0.2 OSX 10.7.5
Related
I am trying to upload a file on its onchange method using Java jersey REST api.
below is the input type:
<input type="file" onchange="uploadFile($event)"/>
i am getting the file as
function uploadFile($event){
console.log($event.files[0].name)
}
below is my rest upload serivce
#Path("/file")
public class FileUpload {
public static final String UPLOAD_FILE_SERVER = "C://Users//Feroz//Documents//filefolder//";
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/upload")
public Response getMsg( #FormDataParam("file") InputStream fileInputStream,
#FormDataParam("file") FormDataContentDisposition fileFormDataContentDisposition) {
System.out.println("ss");
String fileName = null;
String uploadFilePath = null;
try {
fileName = fileFormDataContentDisposition.getFileName();
System.out.println(fileName);
uploadFilePath = writeToFileServer(fileInputStream, fileName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JsonObject json = new JsonObject();
json.put("success", true);
json.put("status", "success");
json.put("path","http://localhost:8080/rest/files/download/Book1.xlsx");
return Response.status(200).entity(json).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "accept, Cache-Control, content-type, x-requested-with")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT,OPTIONS").allow("OPTIONS").build();
}
private String writeToFileServer(InputStream inputStream, String fileName) throws IOException {
OutputStream outputStream = null;
String qualifiedUploadFilePath = UPLOAD_FILE_SERVER + fileName;
try {
outputStream = new FileOutputStream(new File(qualifiedUploadFilePath));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.flush();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
finally{
//release resource, if any
outputStream.close();
}
return qualifiedUploadFilePath;
}
}
How can i send FormDataParam and FormDataContentDisposition file from this onchange method ? I m not sure how to make ajax call which will provide these two params for rest service
In the html form , you need the id and enctyple
<form id="frm-file" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<button type="button" onclick="uploadFile()" />
</form>
In the js, you need jquery.form.js
function uploadFile(){
$.ajaxForm({
"formId": "frm-file",
"method": "POST",
"actionURL": context_path + "upload",
"successFun": function (data) {
}
});
}
In the java, The requestParam is the name value of the input in the form
#POST
#Path("/upload")
public Response getMsg(#RequestParam("file") MultipartFile multipartFile) {
}
I am trying to upload an image from the client using an AJAX call to a Rest Service. What I have is uploading the image. The size of the image matches exactly, and in windows explorer, the image preview looks like my image. But, when I double click the .png file, the image is blank.
What am I doing wrong?
Client: (event.target.files[0] is the file selected from a file dialog box)
let file = event.target.files[0];
$.ajax({
url: URL.BUILDER_URL + '/megaUpload',
type: 'POST',
contentType : "multipart/form-data",
data: file,
processData: false
});
Server:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
#Path("megaUpload")
public Response upload(InputStream fileInputStream) throws Exception {
String uploadFileLocation = "C:\\temp\\bla.png";
OutputStream out = new FileOutputStream(new File(uploadFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadFileLocation));
while ((read = fileInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
return null;
}
// Step 1
function doSubmit(data1, data2){
$("#dataForm").remove();
var form = '';
form += '<form name="dataForm" id="dataForm" action="" target="hiddenIframe" method="post" enctype="multipart/form-data" accept-charset="UTF-8">';
form += '<input type="text" name="data1" id="data1"/>';
form += '<input type="text" name="data2" id="data2"/>';
form += '<div name="dataFormTarget" id="dataFormTarget" style="display:none">';
form += '</div>';
form += '</form>';
$('body').append(form);
$("#dataForm data1").val(data1);
$("#dataForm data2").val(data2);
$("#dataForm").attr("action", "/download/fileDownload.do");
$("#dataForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "/download/fileDownload.do",
async : true,
type : "POST",
data : {
"data1" : data1,
"data2" : data2
},
contentType : "application/x-www-form-urlencoded; charset=UTF-8",
processData : true,
success : function(data){
var blob=new Blob([data]);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="testFile.zip";
link.click();
}
});
});
$("#dataForm").submit();
}
// Step 2
#RequestMapping(value = "/download/fileDownload.do")
public ModelAndView fileDownload(HttpServletRequest request, HttpServletResponse response, ModelAndView mav) throws Exception {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
Parameter inMap = rDictionary(request, response);
Parameter outMap = new Parameter();
Parameter errorMap = new Parameter();
File file = null;
try {
file = new File(inMap.get("data1"));
errorMap = Util.putErrorMap(ErrConst.ERROR_SUCCESS_CODE, null, inMap);
} catch (Exception e) {
e.printStackTrace();
}
mav.addObject("outMap", outMap);
mav = new ModelAndView("downloadView", "downloadFile", file);
return mav;
}
// Step 3
public class DownloadView extends AbstractView {
private static final Logger logger = LogManager.getLogger(DownloadView.class);
public DownloadView() {
setContentType("application/download; charset=utf-8");
}
#Override
protected void renderMergedOutputModel(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
File file = null;
try{
file = (File) model.get("downloadFile");
response.setContentType(getContentType());
response.setContentLength((int) file.length());
String fileName = URLEncoder.encode(file.getName(), "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\""
+ fileName + "\";");
response.setHeader("Content-Transfer-Encoding", "binary");
OutputStream out = response.getOutputStream();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
FileCopyUtils.copy(fis, out);
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException ioe) {
}
}
}
out.flush();
}catch(Exception e){
logger.error("file not found Excpetion !!!["+ file.getPath() +"]");
}
}
}
Hi.
I'm trying to zip file download, using above code.
after download complete, I must need callback function for next download.
When run this code, download is occured.
but downloaded zip file was crashed..
I don't know what is wrong.
Please give me solution.
Thanks.
(Sorry for short english.)
I have a canvas with an image taken from a webcam.
I want to send that image to my server while avoiding any postback. (With a postback, it force the client to validate the use of the webcam everytime they save an image and I don't want that. :( )
Here's the Jscript
function sendPicture() {
event.preventDefault();
var b64 = document.getElementById("canvas").toDataURL("image/png");
b64 = b64.replace('data:image/png;base64,', '');
PageMethods.SaveImage(b64, success, error);
}
function success()
{ console.log("hoorah"); }
function error()
{ console.log("boo"); }
Here's the codebehind which isn't written yet but it doesn't matter since it never reach inside anyways.
[WebMethod]
public static bool SaveImage(string image)
{
return false;
}
The code never reach the WebMethod because the b64 is way too long. (Over 2000 characters)
I tried
var imgObj = new Image();
imgObj.src = b64;
PageMethods.SaveImage(imgObj, success, error);
ain't working.
Help please. :(
Edit : Forgot to put the page html
<div class="formRow">
<input type="button" id="snap" value="Prendre photo" />
<input type="button" id="send" value="Enregistrer Photo" />
<br />
<video id="video" width="320" height="240" autoplay></video>
<canvas id="canvas" width="320" height="240"></canvas>
</div>
I managed to get it done by making a new asp page and sending the b64 by parameter to that page.
New page :
public partial class SaveImage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.Form["data"]))
{
string b64 = Request.Form["data"];
byte[] binary = Convert.FromBase64String(b64);
writeToFile(binary);
}
}
public void writeToFile(byte[] array)
{
var fs = new BinaryWriter(new FileStream(Server.MapPath("~") + "/Images/Photo/" + Session["IdParticipantPhoto"].ToString() + ".png", FileMode.Append, FileAccess.Write));
fs.Write(array);
fs.Close();
}
}
Jscript :
function sendPicture() {
event.preventDefault();
var b64 = document.getElementById("canvas")
.toDataURL("image/png");
b64 = b64.replace('data:image/png;base64,', '');
console.log("Image " + b64);
$.ajax({
type: 'POST',
url: '/LAN/SaveImage.aspx',
data: { "data": b64 },
success: function (msg) {
alert("Uploaded successfully");
}
});
}
Valums file-uploader (now called Fine Uploader) doesn't work under Internet Explorer 9 but wors fine under Chrome.
So under IE it shows the name of the file and button CANCEL and no % of uploading.
Any clue?
UPDATES:
Solution is here as well MVC Valums Ajax Uploader - IE doesn't send the stream in request.InputStream
I know this question was filed under asp.net specifically, but it came up when I searched for "valums ajax upload IE9", so I'll post my fix here in case it helps anyone like myself regardless of language:
I was returning a JSON response from the AJAX upload request with a "application/json" content header. IE9 does not know what to do with "application/json" content (but Chrome/FF/etc do).
I fixed this by making sure to return a "text/html" MIME type http header on my json response from the server.
Now IE is no longer trying to download the response! Cheers
I am unable to reproduce the issue. Here's a full working example.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase qqfile)
{
var uploadPath = Server.MapPath("~/app_data");
if (qqfile != null)
{
var filename = Path.Combine(uploadPath, Path.GetFileName(qqfile.FileName));
qqfile.SaveAs(filename);
return Json(new { success = true }, "text/html");
}
else
{
var filename = Request["qqfile"];
if (!string.IsNullOrEmpty(filename))
{
filename = Path.Combine(uploadPath, Path.GetFileName(filename));
using (var output = System.IO.File.Create(filename))
{
Request.InputStream.CopyTo(output);
}
return Json(new { success = true });
}
}
return Json(new { success = false });
}
}
Index.cshtml view:
<script src="#Url.Content("~/Scripts/valums/fileuploader.js")" type="text/javascript"></script>
<div id="file-uploader">
<noscript>
<p>Please enable JavaScript to use file uploader.</p>
</noscript>
</div>
<script type="text/javascript">
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '#Url.Action("upload")'
});
</script>
You could also include the CSS in your Layout:
<link href="#Url.Content("~/Scripts/valums/fileuploader.css")" rel="stylesheet" type="text/css" />
It seems that is IE cache issue, if you are using Ajax & GET, add timestamp value in the get parameters for the Ajax parameters, that will do the trick like this :
$.ajax({
url : "http:'//myexampleurl.php' + '?ts=' + new Date().getTime(),
dataType: "json",
contentType: "application/json; charset=utf-8",
.
.
//more stuff
If you are using java spring
#RequestMapping(value = "/upload", method = RequestMethod.POST, produces = "application/json")
public #ResponseBody YourObject excelUplaod(#RequestHeader("X-File-Name") String filename, InputStream is) {
// chrome or firefox
}
#RequestMapping(value = "/upload", method = RequestMethod.POST,headers="content-type=multipart/*", produces = "text/html")
public #ResponseBody ResponseEntity<YourObject> uploadByMultipart(#RequestParam(value = "qqfile") MultipartFile file) {
// IE
try {
String fileName = file.getOriginalFilename();
InputStream is = file.getInputStream();
// more stuff
} catch (Exception e) {
logger.error("error reading excel file", e);
}
}