html:
<form action="/upload" method="post" enctype="multipart/form-data">
<input name="upload" type="file">
<input type="submit" value="upload">
</form>
servlet3:
#WebServlet("/upload")
#MultipartConfig
public class UploadFileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public UploadFileServlet() {
super();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part filePart = request.getPart("upload");
String header = filePart.getHeader("Content-Disposition");
String filename = header.substring(header.indexOf("filename=\"") + 10, header.lastIndexOf("\""));
System.out.println(filename);
InputStream in = filePart.getInputStream();
OutputStream out = new FileOutputStream("D:/temp.png");
byte[] buffer = new byte[1024];
int length = -1;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
in.close();
out.close();
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
in this way, I can upload file successfully, but I'd like to deal it in struts2 the same way, code block below:
public void newTask() throws Exception {
Part filePart = request.getPart("file");
String header = filePart.getHeader("Content-Disposition");
String _filename = header.substring(header.indexOf("filename=\"") + 10, header.lastIndexOf("\""));
InputStream in = filePart.getInputStream();
OutputStream out = new FileOutputStream("D://temp.png");
StreamUtils.copy(in, out);
}
but it doesn't work, I can't get anything from Part, it throw NullPointException, what should I do to change my code or it can't work in strut2 use the same way connect file with servlet3?
Related
I'm creating a web app using Java servlets and JSPs and I want to create an upload form in JSP for my clients to be able to upload and download stuff. I'm using Cloud Storage and my default bucket to upload stuff.
I followed Google's tutorial on Reading and Writing to Google Cloud Storage.
This is my Servlet:
public class Create extends HttpServlet {
public static final boolean SERVE_USING_BLOBSTORE_API = false;
private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
.initialRetryDelayMillis(10)
.retryMaxAttempts(10)
.totalRetryPeriodMillis(15000)
.build());
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFilename fileName = getFileName(req);
if (SERVE_USING_BLOBSTORE_API) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey = blobstoreService.createGsBlobKey(
"/gs/" + fileName.getBucketName() + "/" + fileName.getObjectName());
blobstoreService.serve(blobKey, resp);
} else {
GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, BUFFER_SIZE);
copy(Channels.newInputStream(readChannel), resp.getOutputStream());
}
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = getFileName(req);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
copy(req.getInputStream(), Channels.newOutputStream(outputChannel));
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}
}
I can upload and download successfully, but only text and not real files like images, pdfs, etc., which is my problem.
This tutorial is for reading and writing text but i want to upload real files. As you can see from my jsp the enctype is "text/plain":
<form action="/index.html" enctype="text/plain" method="get" name="putFile" id="putFile">
<div>
Bucket: <input type="text" name="bucket" />
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<textarea name="content" id="content" rows="3" cols="60"></textarea>
<br />
<input type="submit" onclick='uploadFile(this)' value="Upload Content" />
</div>
</form>
I tried to change it to "multipart/form-data" and put a
<input name="content" id="content" type="file">
but this does not upload the real file only the fake path of the file.
And I want to know how to upload real files, any help would be appreciated.
Here is one example on how to upload blobs to Cloud Storage:
First you initialize the storage with these lines:
private static Storage storage = null;
// [START init]
static {
storage = StorageOptions.getDefaultInstance().getService();
}
// [END init]
You may change the code to accept different file extensions according to your needs on the getImageUrl method in the line String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
/**
* Extracts the file payload from an HttpServletRequest, checks that the file extension
* is supported and uploads the file to Google Cloud Storage.
*/
public String getImageUrl(HttpServletRequest req, HttpServletResponse resp,
final String bucket) throws IOException, ServletException {
Part filePart = req.getPart("file");
final String fileName = filePart.getSubmittedFileName();
String imageUrl = req.getParameter("imageUrl");
// Check extension of file
if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
final String extension = fileName.substring(fileName.lastIndexOf('.') + 1);
String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
for (String s : allowedExt) {
if (extension.equals(s)) {
return this.uploadFile(filePart, bucket);
}
}
throw new ServletException("file must be an image");
}
return imageUrl;
}
Here a timestamp is appended in the filename which can be a good idea if you want to make the filename unique.
/**
* Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME
* environment variable, appending a timestamp to end of the uploaded filename.
*/
#SuppressWarnings("deprecation")
public String uploadFile(Part filePart, final String bucketName) throws IOException {
DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
DateTime dt = DateTime.now(DateTimeZone.UTC);
String dtString = dt.toString(dtf);
final String fileName = filePart.getSubmittedFileName() + dtString;
// the inputstream is closed by default, so we don't need to close it here
BlobInfo blobInfo =
storage.create(
BlobInfo
.newBuilder(bucketName, fileName)
// Modify access list to allow all users with link to read file
.setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
.build(),
filePart.getInputStream());
// return the public download link
return blobInfo.getMediaLink();
}
In this documentation you'll find more details: https://cloud.google.com/java/getting-started/using-cloud-storage#uploading_blobs_to_cloud_storage
The complete code for this example is in github: https://github.com/GoogleCloudPlatform/getting-started-java/blob/master/bookshelf/3-binary-data/src/main/java/com/example/getstarted/util/CloudStorageHelper.java
I found a solution.
This is my JSP:
<form action="/create" enctype="multipart/form-data" method="post" name="putFile" id="putFile">
<div>
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<input type="submit" value="Upload Content" />
</div>
</form>
When i submit the form, it goes into this Servlet:
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Part filePart = req.getPart("content"); /*Get file from jsp*/
/*Get file name of file from jsp*/
String name = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = new GcsFilename(BUCKET_NAME, name);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
/*Pass the file to copy function, wich uploads the file to cloud*/
copy(filePart.getInputStream(), Channels.newOutputStream(outputChannel));
req.getRequestDispatcher("download.jsp").forward(req, resp);
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}
asp.net client
.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Image_Identify.aspx.cs"
Inherits="WebApplication.iva.Image_Identify" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server" enctype="multipart/form-data" method="post">
<div>
<asp:Button ID="Button_Post" runat="server" Text="submit" OnClick="Button_PostWebRequest" />
</div>
</form>
</body>
</html>
.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
namespace WebApplication.iva
{
public partial class Image_Identify : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string postUrl = "http://xxx/WebUploadHandleServlet";
string paramData = "E:\\1111.jpg";
string ret = string.Empty;
Encoding dataEncode = Encoding.UTF8;
try
{
byte[] byteArray = dataEncode.GetBytes(paramData);
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
webReq.Method = "POST";
webReq.ContentType = "multipart/mixed";
webReq.ContentLength = byteArray.Length;
Stream newStream = webReq.GetRequestStream();
newStream.Write(byteArray, 0, byteArray.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
ret = sr.ReadToEnd();
sr.Close();
response.Close();
newStream.Close();
}
catch (Exception ex)
{
Response.Write("<script>alert('" + ex.Message + "')</script>");
}
}
protected void Button_PostWebRequest(object sender, EventArgs e)
{
}
}
}
java server
#WebServlet(asyncSupported = true, urlPatterns = { "/WebUploadHandleServlet" })
public class WebUploadHandleServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final long MAXSize = 1024 * 1024 * 4 * 2L;// 4*2MB
private String filedir = null;// before
private String resdir = null;// after
/**
* #see HttpServlet#HttpServlet()
*/
public WebUploadHandleServlet() {
super();
}
/**
* #see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init...");
JNIDispatcher.getInstance();
filedir = config.getServletContext().getRealPath("WEB-INF/original_images");
resdir = config.getServletContext().getRealPath("WEB-INF/result_images");
File file1 = new File(filedir);
File file2 = new File(resdir);
if (!file1.exists() && !file2.exists()) {
System.out.println("create dir");
file1.mkdir();
file2.mkdir();
System.out.println("create success");
}
System.out.println("filedir=" + filedir);
System.out.println("resdir=" + resdir);
super.init(config);
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("receive request");
double begin_time = System.currentTimeMillis();
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//FileUpload upload = new FileUpload(factory);20161005
upload.setSizeMax(-1);
upload.setHeaderEncoding("utf-8");
ImageDispose disposer = new ImageDispose(filedir, resdir);
// response.setContentType("text/html");
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String respondResult = null;
String filename = null;
try {
List<FileItem> items = upload.parseRequest(request);
if (items != null && !items.isEmpty()) {
System.out.println("items size:" + items.size());
double start_time = System.currentTimeMillis();
for (FileItem fileItem : items) {
filename = fileItem.getName();
String filepath = filedir + File.separator + filename;
System.out.println("file save path:" + filepath);
InputStream inputStream = fileItem.getInputStream();
respondResult = disposer.process(inputStream, filename);
inputStream.close();
fileItem.delete();
}
double end_time = System.currentTimeMillis();
System.out.println("JNI handle" + filename + "time:" + (end_time - start_time) + "ms");
System.out.println("total time:" + (end_time - begin_time));
}
out.write(respondResult);
} catch (Exception e) {
e.printStackTrace();
out.write("文件" + filename + "upload fail:" + e.getMessage());
}
System.out.println("finish!");
}
#Override
public void destroy() {
System.out.println("release JNI...");
JNIDispatcher.getInstance().releaseJNI();
super.destroy();
}
}
I have printed the result as below.
It seems that java server has received the http request but cannot resolve.
Hope for help!
I have implemented drag & drop file uploading in jsp and servlet, but I have a problem. Here is a part of my upload.jsp code:
function dropUpload(event) {
var files = event.dataTransfer.files;
upload(files);
}
function upload(files) {
var formData = new FormData();
for (var i in files) {
formData.append('file[]', files[i]);
}
var xhr = new XMLHttpRequest();
xhr.onload = function() {
console.log(xhr.responseText);
};
xhr.open("POST", "UploadServlet");
xhr.send(formData);
}
I use the getParts() method in my UploadServlet.java code to get the files that the user uploads, like below:
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public UploadServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("login.jsp").forward(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String savePath = "D:\\TEST";
// creates the save directory if it does not exists
File fileSaveDir = new File(savePath);
if (!fileSaveDir.exists()) {
fileSaveDir.mkdir();
}
response.getWriter().println(request.getParts().size());
for (Part part : request.getParts()) {
if(part.getContentType() == null) {
continue;
}
response.getWriter().println("Part name: " + part.getName());
response.getWriter().println("Size: " + part.getSize());
response.getWriter().println("Content Type: " + part.getContentType());
String fileName = extractFileName(part, response);
response.getWriter().println(fileName);
part.write(savePath + File.separator + fileName);
response.getWriter().println("already upload file:" + fileName);
response.getWriter().println("=============================================");
}
}
private String extractFileName(Part part,HttpServletResponse response) throws IOException {
String contentDisp = part.getHeader("content-disposition");
//response.getWriter().println(contentDisp);
String[] items = contentDisp.split(";");
for (String s : items) {
if (s.trim().startsWith("filename")) {
return s.substring(s.indexOf("=") + 2, s.length()-1);
}
}
return "";
}
But I can't understand that if I upload 2 files with upload.jsp,
the value of getParts().size() is 4; it means that I always have 2 more files than exactly what I upload, and the 2 external files name and contentType will be null, and it will cause an error in part.write().
My solution is use the if statement
if(part.getContentType() == null) {
continue; }
to ignore the null file.
Can somebody tell me why this happens?
According to this [https://stackoverflow.com/a/24264878/2382770][1] answer (it's no accepted) I try read image file from OpenShift DATA_DIR but get message in browser:
Image «http://app-name.rhcloud.com/GetImageServlet?img=681265.jpg»
can not be shown since contains errors."
#WebServlet("/GetImageServlet")
public class GetImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("img");
String uploadFilePath = ...;
System.out.println(uploadFilePath);
byte[] imageBytes = getImageAsBytes(uploadFilePath);
response.setContentType("image/jpeg");
response.setContentLength(imageBytes.length);
response.getOutputStream().write(imageBytes);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
public byte[] getImageAsBytes (String ImageName) throws IOException {
// open image
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage .getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return ( data.getData() );
}
private static final long serialVersionUID = 1L;
}
Do we realy can get data from OpenShift DATA_DIR ?
The only mistake you made is that you send RAW image data (as read by ImageIO). Change the getImageAsBytes() method to read directly image data from file as they are (e.g. jpeg files contains image encoded in jpeg format) using standard FileInputStream. Alternatively, you can use 'Files.readAllBytes(..)' to read content of file.
I am working in Netbeans IDE and i have wrote JS-code for sending HTTP Request to server:
var idFilterJS;
var isIE;
var eventsTable;
var req;
function applyFilter(){
idFilterJS = getRadioValue();
var url = "http://applyfilter?action=applyfilterXML&id=" + idFilterJS;
req = initRequest();
req.open("GET", url, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.onreadystatechange = applyFilterCallBack;
req.send(null);
}
function getRadioValue() {
var inputs = document.getElementsByName("filter");
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
return inputs[i].value
}
}
}
function initRequest(){
if (window.XMLHttpRequest) {
if (navigator.userAgent.indexOf('MSIE') != -1){
isIE = true;
}
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
isIE = true;
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
The code above, I invoke from .jsp:
<div id="filters-list">
<form name="applyfilter" action="applyfilter">
<fieldset>
<legend>Filters</legend>
<%
for (int i = 0; i < userFilters.size(); i++) {
%>
<input type="radio" name="filter"
value="<%=userFilters.get(i).getId()%>"><%=userFilters.get(i).getName()%>
<br/>
<%
}
%>
<button onclick="applyFilter();">Apply</button>
<!--<button onclick="deleteFilter();">Delete filter</button>-->
</fieldset>
</form>
</div>
This is servlet:
public class ApplyFilterServlet extends HttpServlet {
private ServletContext context;
private List<EventTransfer> eventsTransfer = null;
private HttpSession session = null;
#Override
public void init() throws ServletException {
this.context = getServletContext();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
session = request.getSession();
String action = request.getParameter("action");
Integer targetId = null;
try {
targetId = Integer.parseInt(request.getParameter("id"));
}
catch (NumberFormatException e){
context.getRequestDispatcher("/error.jsp").forward(request, response);
}
StringBuffer stringBuffer = new StringBuffer();
}
}
And web.xml for mapping:
<servlet>
<servlet-name>ApplyFilterServlet</servlet-name>
<servlet-class>controller.ApplyFilterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ApplyFilterServlet</servlet-name>
<url-pattern>/applyfilter</url-pattern>
</servlet-mapping>
Next, I had a breakpoint in ApplyFilterServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
session = request.getSession();
String action = request.getParameter("action");
}
So, "request.getParameter("action");" returns null. Why?
You can pass any data as get-string in send method, instead of null
function applyFilter(){
idFilterJS = getRadioValue();
var url = "applyfilter";
var data = "action=applyfilterXML&id=" + idFilterJS
req = initRequest();
req.open("GET", url, true);
req.onreadystatechange = applyFilterCallBack;
req.send(data);
}