Java Servlet FileUpload error - java

I am learning java servlet programming and I wrote a program to upload files, I'm having a strange problem with the program. when it says it finished uploading the file and when i click the link to see it I get a 404 error and when i check the directory (where the file is supposed to be saved ) its empty. I checked the log and there are no error messages.I got the code from a book I'm using to learn servlet and jsp.
here is my java code
import java.io.*;
import java.util.*;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class FileUpload
*/
#WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public FileUpload() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.print("File upload success. <a href=\"/Project_One/files");
out.print("\">Click here to browse through all uploaded ");
out.println("files.</a><br>");
ServletInputStream sis = request.getInputStream();
StringWriter sw = new StringWriter();
int i = sis.read();
for(;i!=-1 && i!= '\r';i=sis.read())
{
sw.write(i);
}
sis.read(); //ditch \'n'
String delimiter = sw.toString();
while(true)
{
StringWriter h = new StringWriter();
int[] temp = new int[4];
temp[0] = (byte)sis.read();
temp[1] = (byte)sis.read();
temp[2] = (byte)sis.read();
h.write(temp[0]);
h.write(temp[1]);
h.write(temp[2]);
//read header
for(temp[3]=sis.read();temp[3]!=-1;temp[3]=sis.read())
{
if(temp[0] == '\r' &&
temp[1] == '\n' &&
temp[2] == 'r' &&
temp[3] == '\n')
{
break;
}
h.write(temp[3]);
temp[0]= temp[1];
temp[1]= temp[2];
temp[2]= temp[3];
}
String header = h.toString();
int StartName = header.indexOf("name=\"");
int endName = header.indexOf("\"",StartName+6);
if(StartName == -1|| endName == -1)
{
break;
}
String name = header.substring(StartName+6,endName);
if(name.equals("file"))
{
StartName = header.indexOf("filename=\"");
endName = header.indexOf("\"",StartName+10);
String filename = header.substring(StartName+10,endName);
ServletConfig config = getServletConfig();
ServletContext sc = config.getServletContext();
//File file = new File(sc.getRealPath("/files"));
//file.mkdirs();
FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);
//write the file to disk
int length = delimiter.length();
//delimiter ="\r\n"+delimiter;
byte[] body = new byte[delimiter.length()];
for(int j=0;j<body.length-1;j++)
{
body[j]=(byte)sis.read();
fos.write(body[j]);
}
//check it wasn't a 0 length file
//if(!delimiter.equals(new String (body)))
//{
int e = body.length-1;
i=sis.read();
for(;i!=-1;i=sis.read())
{
body[e]=(byte)i;
/*fos.write(body[0]);
for(int l=0;l<body.length-1;l++)
{
body[l]=body[l+1];
}*/
//body[e]=(byte)i;
if(delimiter.equals(new String (body)))
{
break;
}
//length++;
fos.write(body[e]);
for(int k=0;k<body.length-1;k++)
{
body[k]=body[k+1];
}
length++;
}
fos.flush();
fos.close();
out.println("<p><b>Saved File:</b>"+filename+"</p>");
out.println("<p><b>Length:</b>"+ length+"</p>");
}
if(sis.read() == '-' && sis.read()=='-')
{
break;
}
}
out.println("</html>");
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
There were few changes made in the code , the changes were given in the book.
here is my HTML code
<html>
<head>
<title>Test HTML Form</title>
</head>
<body>
<p>Select a file to upload or browse currently uploaded files.</p>
<form action="http://127.0.0.1/Project_One/FileUpload"
method="post" enctype="multipart/form-data">
File:<input type="file" name:"file"><br>
<input value="Upload File" type="submit">
</form>
</body>
</html>
I'm using TomCat sever for this.

Where did you get this code from? From a decade old servlet tutorial/book? This is all unnecessarily overcomplicated. Please make sure that you're reading an up to date tutorial/book which is no older than one year.
Here's how the file upload could be done with the standard servlet 3.0 API:
#MultipartConfig
#WebServlet("/FileUpload")
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
String filename = getFilename(filePart);
InputStream filecontent = filePart.getInputStream();
// ... (do your job here)
}
private static String getFilename(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
}
}
return null;
}
}
That's all. It also takes into account that the proper filename is returned. Some browsers such as MSIE namely incorrectly includes the full client side path along the filename. That might be the cause of your problem.
Further there are 2 other problems not directly related:
You should not store the uploaded file in the deploy folder. It will get lost whenever you redeploy the webapp. Store the file in a fixed path somewhere outside the deploy folder. See also for example How I save and retrieve an image on my server in a java webapp.
You should be delegating the job of generating HTML to JSP. In the end of doPost(), forward the request to a JSP:
request.getRequestDispatcher("/WEB-INF/uploadresult.jsp").forward(request, response);
See also:
Our Servlets wiki page - contains hello world examples how to use servlets properly
How to upload files to server using JSP/Servlet?

well i think this code is a bit complicated to read but there are a few points where the error could be, first of all this part :
out.println("<html>");
out.print("File upload success. <a href=\"/Project_One/files");
out.print("\">Click here to browse through all uploaded ");
out.println("files.</a><br>");
In this part your link points to Project_One/files but when you write your file :
FileOutputStream fos = new FileOutputStream(sc.getRealPath("/")+"/"+filename);
you write the file directly in the Project_One folder ( not in the files folder your html points ) , so you could try to see if the file was written in the main folder of your workspace.
Anyway i think you could understand better a code like this :
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) req;
MultipartFile multipartFile = multipartRequest.getFile("file");
byte[] content =multipartFile.getBytes();
File archivoParaGuardar= new File("/your_directory/"+multipartFile.getOriginalFilename());
try {
baos.write(content);
FileOutputStream fos = new FileOutputStream(archivoParaGuardar);
baos.writeTo(fos);
fos.close();
} catch (Exception e) {
logger.error("Error saving file ", e);
}
Hope this helps you.

Related

How to download CSV file from GUI from java spring controller on the go?

I am new in Software Development, just out of college. Doing my first big project.
I am trying to download the CSV file when the user chooses the start date and end date of the project, so the file is supposed to return the project.csv with project name, date from .. to ..
The most important thing is that I am trying to download the file from GUI after clicking on "export" link. All I know is I have to make a spring controller. I have to be missing some part as it's not working.
My java class is writing the csv file to my C disk but it doesn't do the download part. Also CSV file should be written from the database to users computer, not to my disk.
Hope you understand me. Let me know if that's clear.
my code:
ExportController.java
#RestController
#RequestMapping("/config")
public class ExportController {
private String filePath = "C:\\test\\project.csv";
private static final int BUFFER_SIZE = 4096;
#Autowired
private ExportService exportService;
ServletContext context;
#RequestMapping(value = "export/all", method = RequestMethod.POST)
public String list(#RequestParam("startDate")String date, #RequestParam("endDate")String date2, HttpServletResponse response, HttpServletRequest request) throws ServletException, ParseException, IOException {
DateFormat format = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);
Date date_obj = format.parse(date);
Date date2_obj = format.parse(date2);
// get absolute path of the application
ServletContext context = request.getServletContext();
String appPath = context.getRealPath("");
System.out.println("appPath = " + appPath);
// construct the complete absolute path of the file
String fullPath = filePath;
File downloadFile = new File(fullPath);
FileInputStream inputStream = new FileInputStream(downloadFile);
// get MIME type of the file
String mimeType = context.getMimeType(fullPath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
System.out.println("MIME type: " + mimeType);
CsvWriterProject.savetofile();
String csv = "Employee FN/LN: Eatrick Hughes Contract type: External, Activity: WAR, Effort date: 2016-02-17, Name: udfuhfd, Entity: BA, Start date: 2016-02-17, End_date: 2016-02-18";
response.setContentType("application/csv");
response.setHeader("Content-Disposition", "attachment; filename=project.csv");
response.setHeader("Pragma", "public");
response.setHeader("Expires", "0");
response.setHeader("Content-Length", String.valueOf(csv.length()));
response.setHeader("Content-type","application/csv");
// response.setContentType(mimeType);
// response.setContentLength((int) downloadFile.length());
// get output stream of the response
OutputStream outStream = response.getOutputStream();
PrintWriter pw = new PrintWriter(outStream);
pw.print(pw);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
// write bytes read from the input stream into the output stream
while ((bytesRead = inputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.flush();
outStream.close();
return csv;
}
}
Here is angularJS
$scope.export_all = function(item){
$http.post('config/export/all?startDate='+item.startDate+"&endDate="+item.endDate)
.success(function(response) {
$scope.export = response;
});
};
Let me know if you need more information.
You can use HttpServletResponse (javax.servlet.http.HttpServletResponse)
Here is the sample code:
package com.export.test;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/exportTest")
public class ExportControllerTest {
#RequestMapping(value = "/export", method = RequestMethod.GET)
public void exportStream(HttpServletResponse response) {
try {
String responseTosend = "Testing export for rest cliet";
response.getOutputStream()
.write((responseTosend).getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Modify as per your requirement.
Check with docs for more info https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

taking servlet information with submit button [duplicate]

This question already has answers here:
How to call servlet class from HTML form
(2 answers)
Closed 7 years ago.
Im trying to create a Servlet application. When I hit the submit button I want to clear the forms and add the information to a unordered list and store the data. The issue is that I do not know how to evaluate when the button is pushed.
package org.gephi.demos;
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
// Extend HttpServlet class
#WebServlet(name = "HelloWorld", urlPatterns = {"/test"}, loadOnStartup=1)
public class HelloWorld extends HttpServlet {
private String message;
private File f;
private GephiBuilder gb;
//private Main m;
public void init() throws ServletException
{
gb = new GephiBuilder();
System.out.println("Initialized");
// Do required initialization
message = "Hello World for sure";
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Set response content type
response.setContentType("text/html");
//m = new Main(gb);
// Actual logic goes here.
PrintWriter out = response.getWriter();
out.println(HTMLUserInput("do you want a Nodes(n) or auto(a)", "directory", "d"));
String directory = request.getParameter("d");
// do some processing here...
// build HTML code
if(request.getParameter("button")!=null)
{
System.out.println("Hello");
//response.getParameter("d").valu;
String htmlRespone = "<html>";
htmlRespone += "<h2>Your directory is: " + directory + "<br/>";
htmlRespone += "</html>";
// return response
out.println(htmlRespone);
}
//out.println(addJSCode());
}
public String HTMLUserInput(String question, String id, String name){
String htmlOutput = "<form action=\"HelloWorld\"><label>"+question+"</label>"
+"<input name = \""+name+"\" id=\""+id+"\" type=\"text\"/>"
+"<input id=\"button\" type=\"button\">Submit</form>";
return htmlOutput;
}
public void destroy()
{
// do nothing.
}
}
If I press the button nothing changes, I imagine because this code is only evaluated on startup, how do I get it evaluated anytime I press my submit button.
1.You have to use URL for your servlet(wich was specified in servlet mapping) in action attribute . For example: <form action='/test'>
2.There is several way how to submit the form to the server. You can use <input type="submit">Submit</input> inside form tag .
Or if you want to use tag button you have to set id attribute for the form (<form id='myform' .../>) and connect button with the form specifying this id in form attribute:
<button type="submit" form="myform">Submit</button>
And button tag does not have to be located within form tag.
3.After that you can get the content of your form using request.getParameter("input name") and handle these data.
Use <input type="submit" /> instead of <button>
Your urlPatterns = {"/xxxxx"}, should match form action="xxxxx"

spark java: how to handle multipart/form-data input?

I am using spark to develop a web application; the problem occurs when I want to upload a file:
public final class SparkTesting
{
public static void main(final String... args)
{
Spark.staticFileLocation("/site");
Spark.port(8080);
Spark.post("/upload", (request, response) -> {
final Part uploadedFile = request.raw().getPart("uploadedFile");
final Path path = Paths.get("/tmp/meh");
try (final InputStream in = uploadedFile.getInputStream()) {
Files.copy(in, path);
}
response.redirect("/");
return "OK";
});
}
}
But I get this error:
[qtp509057984-36] ERROR spark.webserver.MatcherFilter -
java.lang.IllegalStateException: No multipart config for servlet
at org.eclipse.jetty.server.Request.getPart(Request.java:2039)
at javax.servlet.http.HttpServletRequestWrapper.getPart(HttpServletRequestWrapper.java:361)
at com.github.fge.grappa.debugger.web.SparkTesting.lambda$main$0(SparkTesting.java:20)
at com.github.fge.grappa.debugger.web.SparkTesting$$Lambda$1/920011586.handle(Unknown Source)
at spark.SparkBase$1.handle(SparkBase.java:264)
at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:154)
at spark.webserver.JettyHandler.doHandle(JettyHandler.java:60)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:179)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)
at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:451)
at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:252)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:266)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:240)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527)
at java.lang.Thread.run(Thread.java:745)
And even if I try and specify the type explicitly, as in:
Spark.post("/upload", "multipart/form-data", etc etc)
it will still fail.
I could probably find a library to parse multipart/form-data, grab the whole content and just parse myself, but that'd be a waste.
Can I configure spark to handle that case?
The answer provided by Kai Yao is correct except that when using:
request.raw().setAttribute("org.eclipse.multipartConfig", multipartConfigElement);
use this instead:
request.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
By adding a few lines of code to add the multipart config, you can handle multipart/form-data without an external library:
public Object handle(Request request, Response response) {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp");
request.raw().setAttribute("org.eclipse.multipartConfig", multipartConfigElement);
....
Part file = request.raw().getPart("file"); //file is name of the upload form
}
Source: http://deniz.dizman.org/file-uploads-using-spark-java-micro-framework/
I used apache commons-fileupload to handle this.
post("/upload", (req, res) -> {
final File upload = new File("upload");
if (!upload.exists() && !upload.mkdirs()) {
throw new RuntimeException("Failed to create directory " + upload.getAbsolutePath());
}
// apache commons-fileupload to handle file upload
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(upload);
ServletFileUpload fileUpload = new ServletFileUpload(factory);
List<FileItem> items = fileUpload.parseRequest(req.raw());
// image is the field name that we want to save
FileItem item = items.stream()
.filter(e -> "image".equals(e.getFieldName()))
.findFirst().get();
String fileName = item.getName();
item.write(new File(dir, fileName));
halt(200);
return null;
});
See https://github.com/perwendel/spark/issues/26#issuecomment-95077039
I found complete example here:
https://github.com/tipsy/spark-file-upload/blob/master/src/main/java/UploadExample.java
import spark.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.nio.file.*;
import static spark.Spark.*;
import static spark.debug.DebugScreen.*;
public class UploadExample {
public static void main(String[] args) {
enableDebugScreen();
File uploadDir = new File("upload");
uploadDir.mkdir(); // create the upload directory if it doesn't exist
staticFiles.externalLocation("upload");
get("/", (req, res) ->
"<form method='post' enctype='multipart/form-data'>" // note the enctype
+ " <input type='file' name='uploaded_file' accept='.png'>" // make sure to call getPart using the same "name" in the post
+ " <button>Upload picture</button>"
+ "</form>"
);
post("/", (req, res) -> {
Path tempFile = Files.createTempFile(uploadDir.toPath(), "", "");
req.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp"));
try (InputStream input = req.raw().getPart("uploaded_file").getInputStream()) { // getPart needs to use same "name" as input field in form
Files.copy(input, tempFile, StandardCopyOption.REPLACE_EXISTING);
}
logInfo(req, tempFile);
return "<h1>You uploaded this image:<h1><img src='" + tempFile.getFileName() + "'>";
});
}
// methods used for logging
private static void logInfo(Request req, Path tempFile) throws IOException, ServletException {
System.out.println("Uploaded file '" + getFileName(req.raw().getPart("uploaded_file")) + "' saved as '" + tempFile.toAbsolutePath() + "'");
}
private static String getFileName(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
return cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
}
Please note that in this example in order to iterate over all files use javax.servlet.http.HttpServletRequest#getParts. Also in this example instead of parsing file name you can simply get it using javax.servlet.http.Part#getSubmittedFileName. And also do not forget to close the stream you get. And also delete the file using javax.servlet.http.Part#delete if needed

JavaScript sending XmlHttpRequest only works in Debug Console

Hello dear commmunity.
I have a problem i cannot seem to solve.
Let me explain what i try to do.
I have a simple JSF-Site with a select file dialog and a submit button.
When a user selects a file and clicks the submit button this file shall be send to a servlet on my server, where it is saved locally and a db entry shall be created that points to the location of the file.
Sounds simple right?
Here is my solution so far:
The JavaScript:
function postUploadedFile() {
var servlet = "UploadImageToServer";
var inputElement = document.getElementById('filedataDecoded');
var fileTypeElement = document.getElementById('filedataType');
var encodedFile = inputElement.textContent;
var fileType = fileTypeElement.textContent;
inputElement.textContent = "";
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://localhost:8080/TestJSF/" + servlet + "?fileType="+fileType , true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function () {
if ((xmlhttp.readyState == 4)) {
// handle callback
console.log("done");
}
}
xmlhttp.send(encodedFile);
console.log();
}
My Servlet:
public class UploadImageToServer extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(UploadImageToServer.class);
private String dbUser = "xxxx";
private String dbPw = "xxxx";
public UploadImageToServer() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PreparedStatement stm = null;
Connection con = null;
InputStream fileDataStream = request.getInputStream();
int fileContentLength = request.getContentLength();
String fileType = (request.getParameter("fileType")).split("\\.")[1];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] fileDataBytes64 = new byte[fileContentLength];
byte[] bufferTemp = new byte[1024];
int nRead;
while ((nRead = fileDataStream.read(bufferTemp, 0, bufferTemp.length)) != -1) {
buffer.write(bufferTemp, 0, nRead);
}
buffer.flush();
String tempString = buffer.toString();
String base64String = tempString.split("base64,")[1];
System.out.println("test");
Double newRandom = (double) -1;
while(newRandom < 5000 || newRandom > 1000000) {
newRandom = Math.random() * 10000;
}
String valueOf = String.valueOf((newRandom));
String fileName = (valueOf.split("\\."))[0] + "." + fileType;
File tempFile = new File("C:\\storage\\" + fileName);
byte[] fileDataDecoded = Base64.decodeBase64(base64String);
tempFile.getParentFile().mkdir();
tempFile.createNewFile();
FileOutputStream foS = new FileOutputStream(tempFile);
foS.write(fileDataDecoded);
foS.close();
String driver = PossibleDbDriver.MYSQL.getIdentifier();
try {
Class.forName(driver);
} catch (ClassNotFoundException e2) {
logger.error("Error - no valid Driver-Class specified - [" + driver + "]");
logger.error("Message - [" + e2.getMessage() + "]");
}
String dbURL = "jdbc:mysql://localhost:3306/imagetest";
try {
con = (Connection) DriverManager.getConnection(dbURL,dbUser,dbPw);
stm = con.prepareStatement("INSERT INTO images (image_name,image_path,image_likes,image_dislikes,image_timestamp) VALUES(?,?,?,?,?)");
stm.setString(1, tempFile.getName());
stm.setString(2, tempFile.getPath());
stm.setDouble(3, 0);
stm.setDouble(4, 0);
stm.setTimestamp(5, new Timestamp(GregorianCalendar.getInstance().getTimeInMillis()));
stm.execute();
} catch (SQLException e) {
logger.error("Error - Connection could not be established.");
logger.error("Message - [" + e.getMessage() + "]");
}
}
}
Servlet Mapping:
<servlet>
<description></description>
<display-name>UploadImageToServer</display-name>
<servlet-name>UploadImageToServer</servlet-name>
<servlet-class>mk.imageboard.servlets.UploadImageToServer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadImageToServer</servlet-name>
<url-pattern>/UploadImageToServer</url-pattern>
</servlet-mapping>
The file data comes from another script that reads it as a Base64-String and writes it to the TextArea-Element 'filedataDecoded' (Just to clarify this).
The Application Server is Tomcat 6.0.36 and the JSF implementation is MyFaces 2.1.13.
Everything runs on the same machine(my computer).
Now to my actual problem...
When i let Tomcat run in normal mode and access my site and try to upload a file, the XmlHttpRequest is not send. However when i do the same thing with opened JavaScript Console in Chrome and set breakpoints to:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://localhost:8080/TestJSF/" + servlet + "?fileType="+fileType , true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function () {
if ((xmlhttp.readyState == 4)) {
// handle callback
console.log("done");
}
}
xmlhttp.send(encodedFile);
and step through the script, the request is send and the servlet works fine.
I searched stackoverflow for a solution but couldn't find any. Same with the internet. It's such a weird error and i can't understand why it does not work.
If someone could help me out i would really appreciate it.
Thanks in advance
Chris
Try to use relative path instead of absolute path.
xmlhttp.open("POST", "TestJSF/" + servlet + "?fileType="+fileType , true);
or
xmlhttp.open("POST", "" + servlet + "?fileType="+fileType , true);
Update:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
xmlhttp.open("GET", "TestJSF/" + servlet + "?fileType="+fileType , true);
or
xmlhttp.open("GET", "" + servlet + "?fileType="+fileType , true);
Ok. I think I have found the solution or the cause of the problem.
Somehow the <h:form>...</h:form> surrounding the actual submit button firing the javascript prevented the sending of the request, but as to why it does, I don't know. I deleted the form and it works now correctly.
Does someone have a guess on why this caused the problem? I would really like to know.
But thanks anyway guys. Have a happy new year :)
With kind regards
Chris
EDIT: The missing HTML-Snipped of my site. Sorry I should have added it, my bad!
<ui:define name="content">
<!-- Testbereich -->
<fieldset>
<input type="file" id="file" name="file" enctype="multipart/form-data" onchange=""/>
<input type="submit" value="Verschluesseln" onclick="loadUploadedFile();"/>
</fieldset>
<fieldset>
<div> Uploaddaten nicht verschluesselt:</div>
<h:inputTextarea id="filedataType" styleClass="textareaOutput" disabled="true"/>
<h:inputTextarea id="filedataDecoded" styleClass="textareaOutput" disabled="true"/>
</fieldset>
<!-- <h:form id="uploadForm"> -->
<fieldset>
<input type="submit" onclick="postUploadedFile();"/>
</fieldset>
<!-- </h:form> -->
</ui:define>
To clarify loadUploadedFile() is the javascript that reads the file and returns the Base64 String.

In GWT how do I display an image from the appengine server given the string version of the blobstore key

In GWT how do I display an image from the appengine server side blobstore given the string version of the key?
I think I have stored an image as a blob on the appengine. can someone tell me if it's correct?
try
{
FileService fileService = FileServiceFactory.getFileService();
AppEngineFile file = fileService.createNewBlobFile(content_type, fileName);
boolean lock = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
byte[] b1 = new byte[BUFFER_SIZE];
int readBytes1;
while ((readBytes1 = is.read(b1)) != -1)
{
writeChannel.write(ByteBuffer.wrap(b1, 0, readBytes1));
}
writeChannel.closeFinally();
item_image_blob_key = fileService.getBlobKey(file).getKeyString();
}
catch (Exception e)
{
System.out.println(e.getLocalizedMessage());
e.printStackTrace(response.getWriter());
}
I sent the key back to the client and I am trying to present the image. I tried using :
ImagesService imagesService = ImagesServiceFactory
.getImagesService();
// Get the image serving URL
String imageUrl = imagesService.getServingUrl(blobKey);
but it is deprecated so I tried:
ImagesService imagesService = ImagesServiceFactory.getImagesService();
ServingUrlOptions suo = ServingUrlOptions.Builder.withBlobKey(blobKey);
String image_url = imagesService.getServingUrl(suo);
item.setProperty("image_url", image_url);
Now I get a URL which looks like this:
http://0.0.0.0:8888/_ah/img/5nXYgHwfiMmblDFldDXSew
and get create an image on the client thus:
String image_url = result.get_image_url();
System.out.println("image url is: " + image_url);
Image image = new Image();
image.setUrl(image_url);
RootPanel.get("dynamicDate").add(image);
Only a default image icon appears on the UI
so I created a servlet which accesses the blobstore thus:
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
public class ImageServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
#Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException
{
String blob_key = req.getParameter("blob-key");
if (blob_key != null)
{
BlobKey blobKey = new BlobKey(blob_key);
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
blobstoreService.serve(blobKey, res);
}
else
{
res.sendError(400, "One or more parameters are not set");
}
}
}
and a client http request:
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, "/itemmanager/image");
try
{
Request request = requestBuilder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception)
{
System.out.println(exception.getMessage());
}
public void onResponseReceived(Request request, Response response)
{
System.out.println("so far so good");
System.out.println(response.getHeadersAsString());
if (200 == response.getStatusCode())
{
}
else
{
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
I seem to be getting text how do i get an input stream or something i can get an image with?
Finally after two days of scouring Google and stack-overflow and trying I got it!
On the server I got the upload url thus:
ImagesService imagesService = ImagesServiceFactory.getImagesService();
ServingUrlOptions suo = ServingUrlOptions.Builder.withBlobKey(blobKey);
String image_url = imagesService.getServingUrl(suo);
item.setProperty("image_url", image_url);
The appengine API produced a url which didn't work on the local mode [I think it has to do with sop cross platform issues]
http://0.0.0.0:8888/_ah/img/mR9SOTSEizec4gZYsRnuEw
but it provided a clue: namely the /_ah/img/ part of the String
So I decided to try it and gave this URL to the image "/_ah/img/mR9SOTSEizec4gZYsRnuEw"
Here is the client side code.
String imageKey = result.get_image_key();
System.out.println("category is: " + result.get_category() + " image blob key is: " + imageKey);
String image_url = result.get_image_url();
System.out.println("image url is: " + image_url);
//This doesn't work at least locally
/*Image image = new Image();
image.setUrl(image_url);
RootPanel.get("dynamicDate").add(image);*/
Image image2 = new Image();
image2.setUrl("/_ah/img/" + imageKey);
RootPanel.get("dynamicDate").add(image2);

Categories