I have a form on my jsp page. In this form i choose a file (zip archive) and after click submmit call servlet to upload this file. For file upload im use Apache Commons FileUlpoad library. After upload im unzip archive. Them i do redict to this jsp.
jsp code:
<form action="Upload_Servlet" method="post" enctype="multipart/form-data">
<div id="up">
<input id="fileUpload1" type="file" name="filename1"value="Browse..."/>
</div>
<div>
<input id="btnSubmit" type="submit" value="Загрузить">
<input type="button" id="del" onclick="deleting()" value="Удалить">
</div>
</form>
servlet code:
public class uploadfile extends HttpServlet
{
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
System.out.println(response.getCharacterEncoding());
response.setCharacterEncoding("UTF-8");
System.out.println(response.getCharacterEncoding());
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("wtpwebapps<br/>");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
writer.println("<HTML>");
writer.println("<HEAD <TITLE> Upload4 </TITLE> </HEAD>");
writer.println("<BODY>");
writer.println("<FORM action = \"Upload_Servlet\" method = \"post\" enctype = \"multipart/form-data\">");
writer.println("<INPUT type = file name = ufile>");
writer.println("<INPUT type = submit value = \"Attach\">");
writer.println("<h1>its not multipart</h1>");
writer.println("</FORM>");
writer.println("</BODY>");
writer.println("</HTML>");
return;
}
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> list=null;
String mifpath= "1";
String path = " ";
String mif = " ";
String from = "\\\\";
String to ="/";
String error="";
try{
list = upload.parseRequest(request);
Iterator<FileItem> it = list.iterator();
response.setContentType("text/html");
while ( it.hasNext() )
{
FileItem item = (FileItem) it.next();
File disk = new File("C:/uploaded_files/"+item.getName());
path = disk.toString();
String code = new String(path.substring(path.lastIndexOf("."), path.length()).getBytes("ISO-8859-1"),"utf-8");
if (code.equalsIgnoreCase(".zip"))
{
mifpath=path;
mif = mifpath.replaceAll(from, to);
item.write(disk);
error=unzip.unpack(mif, "C:/uploaded_files");
}
else
{
error = "Выбранный файл не является архивом zip";
}
}
}
catch ( Exception e ) {
log( "Upload Error" , e);
}
request.setAttribute("error", error);
request.getRequestDispatcher("/Home.jsp").forward(request, response);
// String redictedURL="http://localhost:8080/redicted_test/Home.jsp";
// response.sendRedirect(redictedURL);
writer.close();
}
}
Now i want to do this on the portal. Its mean that i dont want to reload my jsp after I upload a file. So i have to use Jquery. And i have some questions:
How to submit form to use jquery in my case?
My servlet code will be work in portlet?
How to send parametrs to jps from portlet?
Using Jquery it can be done easily:
Set a click event on the submit button (or on the form submit).
Post data to servlet:
$.ajax({
url : base_url + 'Upload_Servlet',
type : "post",
data:$('form').serialize(),
cache : false,
success : function(data) {
//do some stuff
},
error : function(xhr, status, err) {
//do error stuff
},
timeout : 3000
});
//End ajax call
After the servlet is done, just use the response writer to write an aswer back (If it contains a lot of data, I'd recommend sending a response in the form of json, see here) and then the success callback is called and you can do whatever you like with this data.
IMPORTANT: Since you are submitting a form, you need to use e.preventDefault() so the form will not be actually submitted but rather be handeled by your ajax.
Related
I use Servlet 3.0, PrimeFaces 6.0, WildFly 8.2, Eclipse Neon, Mozilla or Chrome browsers. Despite following these nice links below:
Oracle Tutorial on File Upload
GitHub: getting the original file name example
I am still not able to determine the actual file name of an uploaded file. My problem is that in the below mentioned servlet the method call:
String fileNamer = getFileName(filePart);
gives me back NULL for the file name, i.e. fileNamer is null. What am I doing wrong? Please help:
1.) Here is my controller (servlet):
#WebServlet("/fileUpload")
#MultipartConfig
public class ImageUploadServlet extends HttpServlet {
private 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;
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
HttpSession session = request.getSession(false);
Long savedKundeId = (Long) session.getAttribute(NewCustomerBean.SESSION_ATTRIBUTE_CUST_ID);
Part filePart = null;
PrintWriter pw = null;
try {
filePart = request.getPart("uploadImageForNewCustomerformId");
String fileNamer = getFileName(filePart);
// rest of code not shown here
2.) My view (Prime Faces 6.0 facelet):
<h:form id="newCustomerformId">
<!-- rest of code not shown -->
<p:commandButton type="submit" value="Create Customer"
icon="ui-icon-check"
actionListener="#{newCustomerBean.saveNewCustomer}"
update = "#form"
oncomplete="ajaxUploadFile();"/>
</h:form>
<h:form id="uploadImageForNewCustomerformId"
enctype="multipart/form-data">
<div id="dropzone">
<img id="librarypreview" src='' alt='library'
style="width: 280px; height: 160 px;" /> <select name="top5"
id="flist" size="5" onchange="previewFile()">
</select>
<output id="list"> </output>
</div>
<input id="fileInput" type="file" name = "file"></input>
<span id="uploadStatusId"></span>
</h:form>
3.) My Java Scipt function for ajax-uploading the file:
function ajaxUploadFile() {
var form = document.getElementById('uploadImageForNewCustomerformId');
if (form == null)
return;
var formData = new FormData(form);
for (var i = 0; i < fileList.length; i ++){
//append a File to the FormData object
formData.append("file", fileList[i], fileList[i].name);
}
var uploadStatusOutput = document.getElementById("uploadStatusId");
var request = new XMLHttpRequest();
request.open("POST", "/javakurs3-biliothek-jsf-mobile/fileUpload");
request.responseType = 'text';
request.onload = function(oEvent) {
if (request.readyState === request.DONE) {
if (request.status === 200) {
if (request.responseText == "OK") {
form.action = "/javakurs3-biliothek-jsf-mobile/pages/customers.jsf";
form.submit();
return;
}
}
uploadStatusOutput.innerHTML = "Error uploading image";
} // request.readyState === request.DONE
}; // function (oEvent)
request.send(formData);
};
I was finally was able to solve the problem. As BalusC correctly put it, I am not only doing a preview of the image using Java Script, but also uploading it using Java script. This caused confusion, as PrimeFaces supports an image preview and an image upload using their custom, own tag, as shown here .
p:fileUpload showcase
The problem using this p:fileUpload is that it has its own button for the image submission, or upload. However, I want to both submit my newly entered customer data AND upload the image using EXACTLY ONE button and button click.
The solution to my requirement is that I used the following code in my ImageUploadServlet
for (Part fPart : request.getParts()){
if (fPart.getName()!=null && fPart.getName().equals("file") && StringUtils.isNotEmpty(fPart.getSubmittedFileName())){
fileNamer = fPart.getSubmittedFileName();
filePart = fPart;
break;
}
}
instead of the code I mentioned in my question:
private 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;
}
I know this is a very basic question but there are so many implementations out there and I can't get them to work.
So in my project if the user clicks a button, I'm generating a zip file on a servlet (which is called through an AJAX POST). Naturally, I want that file to get downloaded to the user.
Here's my code for the request:
<button type="button" class="btn btn-info btn-lg" onclick="getZip();">
<span class="glyphicon glyphicon-download"></span> Download clusters (.zip)
</button>
Here's the AJAX for the POST:
function getzip() {
$.ajax({
url:'GetZipServlet',
type:'GET',
});
}
And this is my code for the download:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("Downloading clusters.zip");
/* Generate the directory on the server, then zip it. */
ClinicoGenomic.getInstance().clustersToFiles();
ClinicoGenomic.getInstance().zipClusters();
System.out.println("Done generating the .zip");
String parent_dir = System.getProperty("catalina.base");
String filename = "clusters.zip";
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;filename=\"" + filename);
ZipOutputStream zipStream = new ZipOutputStream( response.getOutputStream() );
ZipInputStream fi = new ZipInputStream(new FileInputStream(parent_dir + "/" + filename));
int i;
while ((i = fi.read())!=-1)
zipStream.write(i);
zipStream.close();
fi.close();
System.out.println(".zip file downloaded at client successfully");
}
I get the correct messages in my console, up to the .zip file downloaded at client successfully. But the download doesn't start. what could be wrong here???
if you are correctly sending the response you should just simply handle it after your ajax call, like this:
$.ajax({
url:'GetZipServlet',
type:'GET',
success: function (response) {
//handle the response here
}
});
This question already has answers here:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
(6 answers)
Closed 6 years ago.
I'm making a dynamic web project in Eclipse and cannot figure out how to send the result of the query to a jsp file.
This is the servlet doGet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session = request.getSession();
String name = session.getAttribute("user").toString();
String query = "SELECT DISTINCT t.text, t.user, t.date"
+ " FROM users u, tweets t, follows f"
+ " Where t.parent is null"
+ " AND u.id ='"+name + "'"
+ " AND ( f.follower = u.id"
+ " AND f.followed = t.user"
+ " OR t.user = u.id)"
+ " ORDER BY t.date DESC;";
try {
ResultSet rs = Dao.executeQuerySQL(query);
while (rs.next()){
//Get all tweets -> THIS IS THE INFO I WANT TO RETRIEVE
rs.getString(1);
}
}
and this is the timeline.jsp:
<script>
$(document).ready(function(){
});
</script>
This is the timeline!
How I can retrieve here in the jsp the information?
Thanks in advance.
For Servlet section for doGet()
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#EJB
private ProductService productService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
For JSP:
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td>detail</td>
</tr>
</c:forEach>
</table>
Resource Link:
doGet and doPost in Servlets
UPDATE1 for AJAX:
Returning Map as JSON
Here's another example which displays Map<String, String> as <option>:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> options = new LinkedHashMap<>();
options.put("value1", "label1");
options.put("value2", "label2");
options.put("value3", "label3");
String json = new Gson().toJson(options);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
And the JSP:
$(document).on("click", "#somebutton", function() { // When HTML DOM "click" event is invoked on element with ID "somebutton", execute the following function...
$.get("someservlet", function(responseJson) { // Execute Ajax GET request on URL of "someservlet" and execute the following function with Ajax response JSON...
var $select = $("#someselect"); // Locate HTML DOM element with ID "someselect".
$select.find("option").remove(); // Find all child elements with tag name "option" and remove them (just to prevent duplicate options when button is pressed again).
$.each(responseJson, function(key, value) { // Iterate over the JSON object.
$("<option>").val(key).text(value).appendTo($select); // Create HTML <option> element, set its value with currently iterated key and its text content with currently iterated item and finally append it to the <select>.
});
});
});
with
<select id="someselect"></select>
Resource Link:
How to use Servlets and Ajax?
Use one of the jquery ajax functions like .ajax or .get to call the servlet.
Refer to below link for API.
http://api.jquery.com/jquery.ajax/
http://api.jquery.com/jquery.get/
something like this,
$.get( "servlet url here", function( data ) {
$( ".result" ).html( data );
alert( "Load was performed." );
});
In your servlet convert your data to json or html snippet and write to response.
I am trying to upload a file using multipart request through angularjs and receive the content on my Rest service. I am putting up this question here after trying several helps for last 4 days and tiring myself to utmost level. I would appreciate if you can fine tune my approach or suggest another approach (I am open to any suggestions which may work as I am out of ideas now).
Just a pointer, I have tried writing a servlet to read the multipart request sent through angularjs and I got the parts correctly. But I am still putting the angular code here for your reference as I am not better on both angular and rest.
Following is the html extract for file upload:
<div>
<input type="file" data-file-upload multiple/>
<ul>
<li data-ng-repeat="file in files">{{file.name}}</li>
</ul>
</div>
Followingis the angularjs directive code extract:
.directive('fileUpload', function () {
return {
scope: true, //create a new scope
link: function (scope, el, attrs) {
el.bind('change', function (event) {
var files = event.target.files;
//iterate files since 'multiple' may be specified on the element
for (var i = 0;i<files.length;i++) {
//emit event upward
scope.$emit("fileSelected", { file: files[i] });
}
});
}
};
})
Following is the angularjs controller code extract
//a simple model to bind to and send to the server
$scope.model = {
name: "test",
comments: "TC"
};
//an array of files selected
$scope.files = [];
//listen for the file selected event
$scope.$on("fileSelected", function (event, args) {
$scope.$apply(function () {
//add the file object to the scope's files collection
$scope.files.push(args.file);
});
});
//the save method
$scope.save = function() {
$http({
method: 'POST',
url: "/services/testApp/settings/api/vsp/save",
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append("model", angular.toJson(data.model));
for (var i = 0; i < data.files.length; i++) {
formData.append("file" , data.files[i]);
}
return formData;
},
data: { model: $scope.model, files: $scope.files }
}).
success(function (data, status, headers, config) {
alert("success!");
}).
error(function (data, status, headers, config) {
alert("failed!");
});
};
And here is my rest service code:
#Path("/vsp")
public class SampleService{
#Path("/save")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void saveProfile(#FormParam("model") String theXml,
#FormParam("file") List<File> files) throws ServletException, IOException {
final String response = "theXML: " + theXml + " and " + files.size() + " file(s) received";
System.out.println(response);
}
}
And here is the response:
theXML: {"name":"test","comments":"TC"} and 1 file(s) received
The problem is that the content of the file is coming in path and I am not able to get the input stream to read the file. I even tried using
new ByteArrayInputStream(files.get(0).getPath().getBytes())
If the content is text (like txt or csv) it works, but if the content is any other file like xls etc, the retrieved content is corrupt and unusable. Also tried using Jeresy api, but with same result. Am I missing anything obvious? Any help is appreciated.
I came across a few links, but none worked for me. So finally, I had to write a servlet to read the multipart request and added the files and the request parameters as request attributes. Once the request attributes are set, I forwarded the request to my Rest service.
Just for the record, if the multipart request is read once to extract the parts, the request will not have the parts in the forwarded servlet. So I had to set them as request attributes before forwarding.
Here is the servlet code:
public class UploadServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// process only if its multipart content
RequestContext reqContext = new ServletRequestContext(request);
if (ServletFileUpload.isMultipartContent(reqContext)) {
try {
List<FileItem> multiparts = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest(request);
ArrayList<FileItem> fileList = new ArrayList<FileItem>();
request.setAttribute("files", fileList);
for (FileItem item : multiparts) {
if (!item.isFormField()) {
fileList.add(item);
} else {
request.setAttribute(item.getFieldName(),
item.getString());
}
}
request.setAttribute("message", "success");
} catch (Exception ex) {
request.setAttribute("message", "fail"
+ ex);
}
} else {
request.setAttribute("message",
"notMultipart");
}
System.out.println(request.getRequestURI().substring(request.getRequestURI().indexOf("upload")+6));
String forwardUri = "/api" + request.getRequestURI().substring(request.getRequestURI().indexOf("upload")+6);
request.getRequestDispatcher(forwardUri)
.forward(request, response);
}
}
Any request starting with /upload/<rest api path> will be received by the servlet and once the attributes are set, they will be forwarded to /api/<rest api path>.
In the rest api, I used the following code to retrieve the parameters.
#Path("/vsp")
public class SampleService{
#Path("/save")
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void saveProfile(#Context HttpServletRequest request,
#Context HttpServletResponse response) throws Exception {
// getting the uploaded files
ArrayList<FileItem> items = (ArrayList<FileItem>)request.getAttribute("files");
FileItem item = items.get(0);
String name = new File(item.getName()).getName();
item.write( new File("C:" + File.separator + name));
// getting the data
String modelString = (String)request.getAttribute("model");
// Getting JSON from model string
JSONObject obj = JSONObject.parse(modelString);
String responseString = "model.name: " + obj.get("name") + " and " + items.size() + " file(s) received";
System.out.println(responseString);
}
}
I want to upload image with RestTemplate client and get that POST request with Spring base REST sever and save on server. Can any one please help me to how to do this with my Spring base client and server. Thanks
Some of my Spring REST API base server methods are as below,
#RequestMapping(value="user/upload/{imageFile}", method=RequestMethod.POST)
public #ResponseBody User upload(#RequestBody User user, #PathVariable File imageFile, HttpServletResponse response) {
// TODO - How I get this image and file and save, whether I can POST this image file with User object
}
Some of my remote client's Spring RestTemplate base codes are as below,
User newUser = new User();
Map<String, String> vars = new HashMap<String, String>();
vars.put("imageFile", imageFile);
ResponseEntity<User> REcreateUser = restTemplate.postForEntity(IMC_LAB_SKELETON_URL + "/user/upload/{imageFile}", newUser, User.class, vars);
User createUser = REcreateUser.getBody();
// TODO - How I can POST this image file as a parameter or content of the User object
This is a piece of code I wrote time ago (you could pass the filename as a #PathVariable):
server side:
#RequestMapping(value = "/file", method = RequestMethod.POST)
public String uploadFile(#RequestParam MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
//add your logics here
//File newFile = new File("blablabla.xxx");
//file.transferTo(newFile);
...
test with rest template:
#Test
public void testFileUpload() {
String url = "http://blablabla.com/file";
Resource resource = new ClassPathResource("images/file.xxx");
MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<String, Object>();
mvm.add("file", resource);
ResponseEntity<String> respEnt = rt.postForEntity(url, mvm, String.class);
//logger.info("body: " + respEnt.getBody());
...
this bean is needed (I think it requires some apache commons library but I am not sure and don't remember now)
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="500000"/>
</bean>
Refer below code u can upload multiple files,working fine
<form method="POST" enctype="multipart/form-data"
id="fileUploadForm">
<div class="controls">
<div class="entry input-group col-xs-3">
<input class="btn btn-primary" name="files" type="file">
<span class="input-group-btn">
<button class="btn btn-success btn-add" type="button">
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
</div>
</form>
JS
$(document).ready(function() {
$("#btnSubmit").click(function(event) {
// stop submit the form, we will post it manually.
event.preventDefault();
fire_ajax_submit();
});
});
function fire_ajax_submit() {
// Get form
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
data.append("CustomField", "This is some extra data, testing");
// $("#btnSubmit").prop("disabled", true);
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$.ajax({
method : "POST",
enctype : 'multipart/form-data',
url : "lotConfig/lotImage",
data : data,
// http://api.jquery.com/jQuery.ajax/
// https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
processData : false, // prevent jQuery from automatically
// transforming the data into a query string
contentType : false,
cache : false,
timeout : 600000,
success : function(data) {
jQuery('#lotImageget').html('');
getAllLotiamges();
$('#updateImage').modal('hide');
/*
* $("#result").text(data); console.log("SUCCESS : ", data);
* $("#btnSubmit").prop("disabled", false);
*/
},
error : function(e) {
$("#result").text(e.responseText);
console.log("ERROR : ", e);
// $("#btnSubmit").prop("disabled", false);
}
});
}
Spring controller
#PostMapping(value = "/lotImage")
public ResponseEntity<String> updateLotImage(
#RequestParam("files") MultipartFile[] files,
RedirectAttributes redirectAttributes, HttpSession session)
throws IOException {
logger.info("--got request to update Lot Image--");
StringJoiner sj = new StringJoiner(" , ");
for (MultipartFile file : files) {
if (file.isEmpty()) {
continue; // next pls
}
try {
byte[] bytes = file.getBytes();
Properties prop = new Properties();
String resourceName = "app.properties";
ClassLoader loader = Thread.currentThread()
.getContextClassLoader();
InputStream resourceStream = loader
.getResourceAsStream(resourceName);
try {
prop.load(resourceStream);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String image_path = prop.getProperty("LOT_DESTINATION_IMG");
Path path = Paths.get(image_path
+ file.getOriginalFilename());
Files.write(path, bytes);
sj.add(file.getOriginalFilename());
} catch (IOException e) {
e.printStackTrace();
}
}
logger.info("--Image updated--");
return new ResponseEntity<String>("Success", HttpStatus.OK);
}