In my current spring project, I have a form with some input[type=file]
fields which need be handled by this PropertyEditorSupport class:
public class ImagemEditor extends PropertyEditorSupport {
private String file_path = System.getProperty("user.home")+File.separator+".store"+File.separator+"Pictures";
@Override
public void setAsText(String text) {
...
}
...
}
the image is sent to server as a Base64 String and it's added to the other params by this javascript code:
$('input[type=file]').on("change", function(){
var id = $(this).attr("id");
var name = $(this).attr("name");
if(typeof id !== "undefined") {
if(this.files.length > 0) {
reader = new FileReader();
reader.onloadend = function () {
str += "&" + name + "=" + this.result;
}
reader.readAsDataURL(this.files[0]);
}
}
});
In the PropertyEditorSupport class, I read the String with the Base64 encoded image and convert to byte[]
, just to store this bytes into a file:
byte[] buffer = Base64.decodeBase64(text.split(",")[1]);
File arquivo;
try {
arquivo = new File(file_path+File.separator+file_name()+".jpeg");
} catch (Exception e) {
e.printStackTrace();
arquivo = null;
}
File dir = new File(file_path);
if(!dir.exists())
dir.mkdirs();
if(!arquivo.exists())
try {
arquivo.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
FileOutputStream fileOut;
try {
fileOut = new FileOutputStream(arquivo);
} catch (Exception e) {
e.printStackTrace();
fileOut = null;
}
try {
fileOut.write(buffer);
} catch (Exception e) {
e.printStackTrace();
}
try {
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
but when I try open the resulting image, it isn't the same image I upload (I use the command line tool vbindiff
to verify that, and the header of the image is always the same). It's not even possible open the resulting image (I am using Gwenview on Linux/Kubuntu).
Someone can see what's wrong here?
I tried to put up a very short example using just the jre.
You just need to put the html in index.html
in the working directory, run the server and upload an example image.
This is just example code, so your app will be running on a servlet container of some kind, you will have to adapt code to the actual request and response object you have.
<html>
<head>
<title>Test file</title>
<script type="text/javascript">
function sendFile() {
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function() {
var http = new XMLHttpRequest();
var url = "save_file";
http.open("POST", url, true);
http.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
http.onreadystatechange = function() {//Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
console.info(http.responseText);
}
}
var header = "base64,";
var pos=reader.result.indexOf(header);
var data = reader.result.substring(pos+header.length);
http.send(data);
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
</script>
</head>
<body>
<input type="file" onchange="sendFile()">
<br>
</body>
</html>
package so;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.Base64;
import java.util.Scanner;
import com.sun.net.httpserver.*;
public class LoadImage {
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/save_file",FileSaveHandler());
server.createContext("/", indexHandler());
server.start();
System.out.println("Server started");
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
System.out.println("Server stopped");
server.stop(0);
}
private static HttpHandler indexHandler() {
return new HttpHandler() {
@Override
public void handle(HttpExchange exchange) throws IOException {
File f = new File("index.html");
try(OutputStream responseBody = exchange.getResponseBody();InputStream in = new FileInputStream(f);){
byte[] buffer = new byte[(int)f.length()];
in.read(buffer);
exchange.sendResponseHeaders(200, buffer.length);
responseBody.write(buffer);
}
}
};
}
private static HttpHandler FileSaveHandler() {
return new HttpHandler() {
@Override
public void handle(HttpExchange exchange) throws IOException {
try(InputStream in = exchange.getRequestBody();
OutputStream out = new FileOutputStream("out.jpg")){
byte [] buffer = new byte[3*1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int l = 0;
while((l=in.read(buffer))>=0){
bos.write(buffer, 0, l);
}
byte[] data = Base64.getDecoder().decode(bos.toByteArray());
out.write(data);
}
}
};
}
}