This question already has answers here:
How can I upload files to a server using JSP/Servlet and Ajax?
(4 answers)
Closed 7 years ago.
Trying to upload a file to my servlet without page refresh with ajax.
Been stuck at this for some days now, and just can't let it go.
my form:
<form method="POST" id="changeImage2" enctype="multipart/form-data">
<input type="file" name="photo" /> <br>
<input type="button" value="Change Picture" id="changeImage1">
</form>
my servlet:
#MultipartConfig
public class changeImage extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
Part filePart = req.getPart("photo");
Object email = req.getSession().getAttribute("email");
Object name = req.getSession().getAttribute("name");
try{
Class.forName("com.mysql.jdbc.Driver");
Connection myConn = DriverManager.getConnection("", "", "");
PreparedStatement ps = myConn.prepareStatement("update user set profilePicture=? where email=? and name=?");
ps.setBlob(1, filePart.getInputStream());
ps.setString(2, (String) email);
ps.setString(3, (String) name);
ps.executeUpdate();
} catch (Exception e){
e.printStackTrace();
}
}
}
my ajax/jquery:
<script>
$(document).ready(function() {
$('#changeImage1').click(function() {
var dataForm = $('#changeImage2').serialize();
$.ajax({
type : 'POST',
url : 'changeImage',
data : dataForm,
success : function(data) {
$('#gg1').text(data);
},
error : function() {
$('#gg1').text("Fail");
},
});
});
});
</script>
When running this I get the error:
SEVERE: Servlet.service() for servlet [changeImage] in context with
path [/Event] threw exception
[org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException:
the request doesn't contain a multipart/form-data or
multipart/form-data stream, content type header is null] with root
cause
org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException:
the request doesn't contain a multipart/form-data or
multipart/form-data stream, content type header is null
I tried use another form and do without the ajax/jquery:
<form action="changeImage" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Change Picture" />
</form>
With this it works. So I'm guessing the JDBC and Servlet is sat up properly. And that I'm not using Ajax/Jquery properly.
In your code you write:
ps.setBlob(5, (Blob) InputStream);
According to javadoc for PreparedStatement this int, 5 is the parameter index. As the error is stating you only have 3 parameters.
You need to change this to 3? - looking at your SQL statement I think you may have forgotten you have copied and pasted from somewhere and haven't yet edited it.
These lines are the problem, you can't use Part object as Blob or InputStream. A cast exception should happen there.
Part filePart = req.getPart("photo");
Part InputStream = filePart; //this line is not needed at all
ps.setBlob(1, (Blob) InputStream);
Try something like this
ps.setBlob(1, filePart.getInputStream());
or
ps.setBinaryStream(1, filePart.getInputStream());
Related
Below I have a code that should accept a user's uploaded image in the form of an input element and push it to a MySQL Database. I am using Tomcat 9. Why is it not working yet no exceptions are being thrown? Nothing is being pushed to the database and there is no way of telling to what point the code is being executed. Note that I have embedded the class within the jsp file as IntelliJ has issues with separate servlet classes. Also note that the code was influenced by BalusC's answer. If possible, could anyone suggest an alternative code that can be used instead?
<form action="trial4.jsp" method="post" enctype="multipart/form-data">
<input type="text" name="description"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
static String URL = "localhost:3306/";
static String DATABASE_NAME = "MYDB";
static String USERNAME = "user";
static String PASSWORD = "";
#WebServlet("/upload")
#MultipartConfig
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String description = request.getParameter("description"); // Retrieves <input type="text" name="description">
Part filePart = request.getPart("file"); // Retrieves <input type="file" name="file">
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
InputStream fileContent = filePart.getInputStream();
// ... (do your job here)
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://" + URL + DATABASE_NAME, USERNAME, PASSWORD);
PreparedStatement ps = con.prepareStatement("insert into data(image) values(?)");
ps.setBinaryStream(1, fileContent);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
For other people who are facing a similar challenge, there is a repo that has really helped. The repo owner deserves a cup of coffee.
EDIT 03/2022
The documentation provides a good solution, one that is bettered by the fact that it does not involve third party libraries.
public class Relay extends HttpServlet {
#Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String command = request.getParameter("command");
RequestDispatcher rd =request.getRequestDispatcher(command);
rd.forward(request, response);
System.out.println("Request forwarded to " + command + " servlet");
}
}
This is my Relay servlet, I'm sending data from this form
<form action="Relay" method="POST" enctype="multipart/form-data"> /
<input type="hidden" name="command" value="AddProduct" />
<input type="text" name="pname" value="" />
<input name="" type="submit" value="Add Product">
</form>
It is throwing a java.lang.NullPointerException.
But works fine when I remove this:
enctype="multipart/form-data"
Why do you need to add it then? Just keep it out.
If you need it in order to upload a file by <input type="file"> which you intend to add later on, then you should put #MultipartConfig annotation on your servlet, so that request.getParameter() will work and that all uploaded files can be retrieved by request.getPart().
#WebServlet("/Relay")
#MultipartConfig
public class Relay extends HttpServlet {
// ...
}
See also:
How to upload files to server using JSP/Servlet?
Parameters encoded with multipart/form-data are sent in POST body - not as regular request parameters, therefore can't be read using request.getParamter(...).
Check out Commons file upload package for multipart requests processing.
I am including this just for additional information for troubleshooting.
if you are stuck and want to know about what all parameters are coming through multipart request you can print all parameters using following code.
MultipartRequest multi = <Your code to retrieve multipart request goes here. Sorry but can not post code as I use proprietary APIs>
Enumeration en1 = multi.getParameterNames();
while (en1.hasMoreElements()) {
String strParamName = (String)en1.nextElement();
String[] strParamValues = multi.getParameterValues(strParamName);
for (int i = 0; i < strParamValues.length; i++) {
System.out.println(strParamName + "=" + strParamValues[i]);
}
}
remove the form tag and use
echo <?php form_open_multipart('Controller/function');
I got the same issue whenever I use enctype="multipart/form-data"
I didn't get the file name and when I remove that it was working fine
try it it worked for me
So, I'm having trouble retrieving information from my the client-side jsp. The javascript executes, and the alert prints, however query becomes null in the java servlet, and null is then written to the logger. I can't seem to figure out why the query is now null.
HTML:
<div id="query">
<div id="querybar">
<form onsubmit="query();return false;" method="get">
<input type="text" id="querytext" placeholder="Run a query" name="querytext">
</form>
<div id="queryimg-container">
<img src="styles/magnifyingglass.png" id="queryimg" alt="" />
</div>
</div>
</div>
JS:
function query() {
$.get('QueryHelper', function(data) {
alert("Somesortofalert");
});
}
Java Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String query = request.getParameter("querytext");
response.setContentType("text/plain");
#SuppressWarnings("resource")
PrintWriter writer = response.getWriter();
sLogger.info(query);
}
Can anyone see anything wrong? I'm super stumped here.
It'll be null because no parameter by that name is being sent with the Ajax request.
Despite being started by an onsubmit event, $.get() doesn't have any automatic knowledge of the <form>. It's up to you to gather or specify any parameters to be included with the request using the data parameter.
$.get('QueryHelper', { querytext: 'foo bar' }, function (res) {
// ...
});
Provided you have a reference to the <form> or its inputs, you can use .serialize() to prepare the fields' names and values as data.
<form onsubmit="query(this); return false;" method="get">
<!-- ^^^^ -->
function query(form) {
// ^^^^
$.get('QueryHelper', $(form).serialize(), function (res) {
// ^^^^^^^^^^^^^^^^^^^
// ...
});
}
I am attempting to post data to a servlet where it will be inserted in to a mysql database.
Here is the html form:
<form id="commentForm" name="commentForm" action="http://server.co.uk/dbh" method="POST">
<input type="text" name="name" placeholder="Your name" required="required">
<textarea name="comment" placeholder="Enter your comment here" required="required"></textarea>
<input type="hidden" name="postID" id="postID" value="<%= postID %>">
<input type="submit" name="submit" id="commentSubmit" value="submit">
</form>
The Jquery:
$("#commentSubmit").click(function(e){
var postData = $("#commentForm").serializeArray();
var formURL = $("#commentForm").attr("action");
$.ajax(
{
url : formURL,
type: "POST",
data : postData,
success:function(data, textStatus, jqXHR)
{
$("#commentFormWrap").html("<p>Success</p>");
},
error: function(jqXHR, textStatus, errorThrown)
{
$("#commentFormWrap").html("<p>error: "+errorThrown+"</p>");
}
});
e.preventDefault(); //STOP default action
$("#commentForm").hide();
});
A simplified dbh servlet:
import javax.servlet.annotation.WebServlet;
...
#WebServlet(description = "Handles connection to MySql database", urlPatterns = { "/dbh" })
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
postArray = request.getParameterValues("postData");
commentName = postArray[0];
comment = postArray[1];
postID = Integer.parseInt(postArray[3]);
try{
submitComment();
}catch(Exception e){
e.printStackTrace();
}
}
public void submitComment() throws Exception{
try{
sql="INSERT INTO crm_comments (comment_name, comment_content, comment_date, post_id) VALUES (?, ?, NOW(), ?)";
prep = conn.prepareStatement(sql);
prep.setString(1, commentName);
prep.setString(2, comment);
prep.setInt(3, postID);
rs = prep.executeQuery();
}catch(Exception e){
e.printStackTrace();
}
}
Currently the ajax call is returning the error block error:. But nothing as the errorThrown variable.
From what I can see the servlet is written correctly. Is there something wrong between the html and the Jquery ajax call, that it isn't posting the data to the servlet?
postArray = request.getParameterValues("postData");
I think you can replace this with actual field names
commentName = request.getParameter("name");
comment = request.getParameter("comment");
this will solve your problem
According to the jQuery documentation, the serializeArray method returns a JavaScript array of objects. This method will generate a JSON object from your form, that will look like: [{"name":"name",value:"<your name input value>"},{"name":"comment",value:"<your comment>"},{"name":"postID",value:"<postID value>"} ...]. Only the content of the postData variable will be sent: you won't have any reference at all to that postData keyword in your Servlet.
So in your Servlet, the request.getParameterValues("postData"); call seems to be invalid. Try this instead:
commentName = request.getParameterValues("name");
comment = request.getParameterValues("comment");
postID = Integer.parseInt(request.getParameterValues("postID"));
public class Relay extends HttpServlet {
#Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String command = request.getParameter("command");
RequestDispatcher rd =request.getRequestDispatcher(command);
rd.forward(request, response);
System.out.println("Request forwarded to " + command + " servlet");
}
}
This is my Relay servlet, I'm sending data from this form
<form action="Relay" method="POST" enctype="multipart/form-data"> /
<input type="hidden" name="command" value="AddProduct" />
<input type="text" name="pname" value="" />
<input name="" type="submit" value="Add Product">
</form>
It is throwing a java.lang.NullPointerException.
But works fine when I remove this:
enctype="multipart/form-data"
Why do you need to add it then? Just keep it out.
If you need it in order to upload a file by <input type="file"> which you intend to add later on, then you should put #MultipartConfig annotation on your servlet, so that request.getParameter() will work and that all uploaded files can be retrieved by request.getPart().
#WebServlet("/Relay")
#MultipartConfig
public class Relay extends HttpServlet {
// ...
}
See also:
How to upload files to server using JSP/Servlet?
Parameters encoded with multipart/form-data are sent in POST body - not as regular request parameters, therefore can't be read using request.getParamter(...).
Check out Commons file upload package for multipart requests processing.
I am including this just for additional information for troubleshooting.
if you are stuck and want to know about what all parameters are coming through multipart request you can print all parameters using following code.
MultipartRequest multi = <Your code to retrieve multipart request goes here. Sorry but can not post code as I use proprietary APIs>
Enumeration en1 = multi.getParameterNames();
while (en1.hasMoreElements()) {
String strParamName = (String)en1.nextElement();
String[] strParamValues = multi.getParameterValues(strParamName);
for (int i = 0; i < strParamValues.length; i++) {
System.out.println(strParamName + "=" + strParamValues[i]);
}
}
remove the form tag and use
echo <?php form_open_multipart('Controller/function');
I got the same issue whenever I use enctype="multipart/form-data"
I didn't get the file name and when I remove that it was working fine
try it it worked for me