I'm getting Stream is closed Exception when I'm going to save the uploaded image.
I'm tring to preview graphicImage of uploaded image the before save. This operation is working. But I can't save the image. Here is my code:
private InputStream in;
private StreamedContent filePreview;
// getters and setters
public void upload(FileUploadEvent event)throws IOException {
// Folder Creation for upload and Download
File folderForUpload = new File(destination);//for Windows
folderForUpload.mkdir();
file = new File(event.getFile().getFileName());
in = event.getFile().getInputstream();
filePreview = new DefaultStreamedContent(in,"image/jpeg");
FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void setFilePreview(StreamedContent fileDownload) {
this.filePreview = fileDownload;
}
public StreamedContent getFilePreview() {
return filePreview;
}
public void saveCompanyController()throws IOException{
OutputStream out = new FileOutputStream(getFile());
byte buf[] = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
FileMasterDO fileMasterDO=new FileMasterDO();
fileMasterDO.setFileName(getFile().getName());
fileMasterDO.setFilePath(destination +file.getName());
fileMasterDO.setUserMasterDO(userMasterService.findUserId(UserBean.getUserId()));
fileMasterDO.setUpdateTimeStamp(new Date());
in.close();
out.flush();
out.close();
fileMasterService.save(filemaster);
}
The bean is in the session scope.
You're trying to read an InputStream twice (the first time is in DefaultStreamedContent constructor of upload method and the second time is in the copy loop of the save method). This is not possible. It can be read only once. You need to read it into a byte[] first and then assign it as a bean property so that you can reuse it for both the StreamedContent and the save.
Make sure that you never hold external resources such as InputStream or OutputStream as a bean property. Remove them all from the current and other beans where applicable and use byte[] to hold the image's content as property.
In your particular case, you need to fix it as follows:
private byte[] bytes; // No getter+setter!
private StreamedContent filePreview; // Getter only.
public void upload(FileUploadEvent event) throws IOException {
InputStream input = event.getFile().getInputStream();
try {
IOUtils.read(input, bytes);
} finally {
IOUtils.closeQuietly(input);
}
filePreview = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/jpeg");
// ...
}
public void saveCompanyController() throws IOException {
OutputStream output = new FileOutputStream(getFile());
try {
IOUtils.write(bytes, output);
} finally {
IOUtils.closeQuietly(output);
}
// ...
}
Note: IOUtils is from Apache Commons IO, which you should already have in the classpath as it's a dependency of <p:fileUpload>.
Related
I have my download manager, and it work perfect if I try to download a file. But I have a problem.
I have 4 CardView in my activity and I set it onClickListener, so when I click one CardView it will download the file.
Here is the code to call the download function
cardviewR1 = findViewById(R.id.card_viewR1);
cardviewR1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pDialogDL = new ProgressDialog(this);
pDialogDL.setMessage("A message");
pDialogDL.setIndeterminate(true);
pDialogDL.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialogDL.setCancelable(true);
final DownloadTask downloadTask = new DownloadTask(this);
downloadTask.execute(R1Holder);
pDialogDL.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
});
and here is the download function
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+getString(R.string.r1)+"_"+NameHolder+".zip");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
pDialogDL.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
pDialogDL.setIndeterminate(false);
pDialogDL.setMax(100);
pDialogDL.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
pDialogDL.dismiss();
if (result != null)
Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
}
}
The code work in my app, but the problem is, when I try to add second CardView which is like this
cardviewR2 = findViewById(R.id.card_viewR2);
cardviewR2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pDialogDL = new ProgressDialog(this);
pDialogDL.setMessage("A message");
pDialogDL.setIndeterminate(true);
pDialogDL.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialogDL.setCancelable(true);
final DownloadTask downloadTask = new DownloadTask(this);
downloadTask.execute(R2Holder);
pDialogDL.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloadTask.cancel(true);
}
});
}
});
Yes it will download the second file, but it will overwrite the first file. I think the problem is right here
output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/"+getString(R.string.r1)+"_"+NameHolder+".zip");
Anyone can help me with this code?
I need your help, Thanks
Fixed it by create a new Download Class separately in different file with activity, so the AsyncTask will be call again and again
thanks
I'm using retrofit to upload images on server, image are uploading successfully, but without extension.
Means only image name is uploading to database, extension is not there.
So image became useless for me.
please provide help.
here is my method in interface->
#FormUrlEncoded
#POST("/webservices/AssessorAssetsUpload.php")
Call<ImageModel> uploadImage(
#Field("name")String pictype,
#Field("type")String uploadtype,
#Field("accesser_id")String asses_id,
#Field("paper_schedule_id")String paper_id,
#Field("imagefile")String image
);
my activity code->
String image=imagetoString();
RetrofitInterface retrofit=ApiClient.getApiClient().create(RetrofitInterface.class);
Call<ImageModel> call=retrofit.uploadImage(imageName,"image",assessor_id,paperId,image);
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Call<ImageModel> call, Response<ImageModel> response) {
System.out.println(response.body().getStatus()+" "+response.body().getMsg()+" "+response.body().getUrl());
}
#Override
public void onFailure(Call<ImageModel> call, Throwable t) {
t.printStackTrace();
}
});
}
private String imagetoString(){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
byte[] bytes=stream.toByteArray();
return Base64.encodeToString(bytes,Base64.DEFAULT);
}
We use Multipart instead of formurlencoded in case of any multimedia object.
#Multipart
#POST("/webservices/AssessorAssetsUpload.php")
Call<ImageModel> uploadImage(
#Part("name")RequestBody pictype,
#Part("type")RequestBody uploadtype,
#Part("accesser_id")RequestBody asses_id,
#Part("paper_schedule_id")RequestBody paper_id,
#Part("imagefile")MultipartBody.Part image
);
MultipartBody.Part image=imagetoPart();
RetrofitInterface retrofit=ApiClient.getApiClient().create(RetrofitInterface.class);
Call<ImageModel> call=retrofit.uploadImage(
getTextRequest("imageName"),
getTextRequest("image"),
getTextRequest("assessor_id"),
getTextRequest("paperId"),
image
);
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Call<ImageModel> call, Response<ImageModel> response) {
System.out.println(response.body().getStatus()+" "+response.body().getMsg()+" "+response.body().getUrl());
}
#Override
public void onFailure(Call<ImageModel> call, Throwable t) {
t.printStackTrace();
}
});
}
private String imagetoPart(){
Bitmap bitmap = BitmapFactory.decodeFile("Image Path");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);
byte[] bytes=stream.toByteArray();
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), bytes);
MultipartBody.Part part = MultipartBody.Part.createFormData("name", "name", reqFile);
return part;
}
private RequestBody getTextRequest(String body) {
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), body);
return requestBody;
}
We need to convert the fields into request body and image into a multipart body to send it as a multipart request. This will do your work.
My image files are stored in database (I know they shouldn't be, but can't help).
To be able to render them on clients, I've implemented an async servlet that helps read the binary stream off the database column and write on to the Output Stream of Servlet Response. Traditional IO works just fine here.
When I thought of trying the non blocking IO with async servlet (to test performance), my binary data returned in the response keeps getting corrupted.
Starting with the Oracle Blog, I've seen various examples of file upload with async NIO servlet, but no help with my issue.
Here's the servlet code:
#WebServlet(asyncSupported = true, urlPatterns = "/myDownloadServlet")
public class FileRetrievalServletAsyncNIO extends HttpServlet
{
private static final long serialVersionUID = -6914766655133758332L;
#Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Queue<byte[]> containerQueue = new LinkedList<byte[]>();
AsyncContext asyncContext = request.startAsync();
asyncContext.addListener(new AsyncListenerImpl());
asyncContext.setTimeout(120000);
try
{
long attachmentId = Long.valueOf(request.getParameter("id"));
MyAttachmentDataObject retObj = ServletUtils.fetchAttachmentHeaders(attachmentId);
response = (HttpServletResponse) asyncContext.getResponse();
response.setHeader("Content-Length", String.valueOf(retObj.getContentLength()));
if (Boolean.valueOf(request.getParameter(ServletConstants.REQ_PARAM_ENABLE_DOWNLOAD)))
response.setHeader("Content-disposition", "attachment; filename=" + retObj.getName());
response.setContentType(retObj.getContentType());
ServletOutputStream sos = response.getOutputStream();
ServletUtils.fetchContentStreamInChunks(attachmentId, containerQueue); // reads from database and adds to the queue in chunks
sos.setWriteListener(new WriteListenerImpl(sos, containerQueue, asyncContext));
}
catch (NumberFormatException | IOException exc)
{
exc.printStackTrace();
request.setAttribute("message", "Failed");
}
}
}
Here's the write listener implementation
public class WriteListenerImpl implements WriteListener
{
private ServletOutputStream output = null;
private Queue<byte[]> queue = null;
private AsyncContext asyncContext = null;
private HttpServletRequest request = null;
private HttpServletResponse response = null;
public WriteListenerImpl(ServletOutputStream sos, Queue<byte[]> q, AsyncContext aCtx)
{
output = sos;
queue = q;
asyncContext = aCtx;
request = (HttpServletRequest) asyncContext.getRequest();
}
#Override
public void onWritePossible() throws IOException
{
while(output.isReady())
{
while (!queue.isEmpty())
{
byte[] temp = queue.poll();
output.write(temp, 0, temp.length);
}
asyncContext.complete();
request.setAttribute("message", "Success");
}
}
#Override
public void onError(Throwable t)
{
System.err.println(t);
try
{
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
catch (IOException exc)
{
exc.printStackTrace();
}
request.setAttribute("message", "Failure");
asyncContext.complete();
}
}
The response data looks like this:
What am I doing wrong?
Not sure exactly what you expect the output to look like but in terms of async i/o you should check output.isReady() before every write. So your onWritePossible code should be:
while(output.isReady() && !queue.isEmpty())
{
byte[] temp = queue.poll();
output.write(temp, 0, temp.length);
}
if (queue.isEmpty()) {
asyncContext.complete();
request.setAttribute("message", "Success");
}
This allows onWritePossible() to return if writing becomes blocked which is the basically the point of async I/O.
If you write when writing is blocked (output.isReady() would return false) different implementations may either ignore the write or throw an exception. Either way your output data would be either missing some writes in the middle or truncated.
I have a jsf form that takes an email address, brief description, and image from the user. The else statement below is completely ignored when file==null. If a picture isn't uploaded I want an error telling the user they have to upload a image. How do I accomplish this?
import org.primefaces.model.UploadedFile;
private UploadedFile file;
public UploadedFile getFile() {
return file;
}
public void setFile(UploadedFile file) {
this.file = file;
}
public String upload() {
if (file!=null ) {
try {
System.out.println(file.getFileName());
InputStream fin2 = file.getInputstream();
Connection con = DataConnect.getConnection();
PreparedStatement pre = con.prepareStatement("insert into PICTURE_TABLE (EMAIL_ADDRESS,PRICE,ITEM_DESC,PICTURES,DATE) values(?,?,?,?,?)");
pre.setString(1, email);
pre.setString(2, price);
pre.setString(3,itemDesc);
pre.setBinaryStream(4, fin2, file.getSize());
pre.setString(5,time);
pre.executeUpdate();
System.out.println("Inserting Successfully!");
}
catch (Exception e) {
System.out.println("Exception-File Upload." + e.getMessage());
return "imageFail";
}
}
else{
FacesMessage msg = new FacesMessage("Please select image!!");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
this is the jsf tag I'm using.
<h:form enctype="multipart/form-data"
I am making an Application in J2ME, with the use of this application user will be able to capture an image and at the same time upload that image to Web Server, but whenever I use this app in my Nokia C series I am not able to capture an image and whenever use this application via Computer able to capture an image but send command is not working please see the problem and sort out this problem, and guide what I need to do to make this app helpful and useful for me …………….Thanks Amit here
public class myMidlet extends MIDlet implements CommandListener{
private Display display;
private Form form;
private Command exit, back, capture, camera, send;
private Player player;
private VideoControl videoControl;
private Video video;
int status = 0;
byte localData[];
public myMidlet() {
display = Display.getDisplay(this);
form = new Form("My Form");
exit = new Command("Exit", Command.EXIT, 0);
camera = new Command("Camera", Command.SCREEN, 1);
back = new Command("Back", Command.BACK, 2);
capture = new Command("Capture", Command.SCREEN, 3);
send = new Command("Send", Command.OK, 1);
form.addCommand(camera);
form.addCommand(exit);
form.setCommandListener(this);
}
public void startApp() {
display.setCurrent(form);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional){
notifyDestroyed();
}
public void commandAction(Command c, Displayable s){
String label = c.getLabel();
if (label.equals("Exit")){
destroyApp(true);
} else if (label.equals("Camera")) {
showCamera();
} else if (label.equals("Back"))
display.setCurrent(form);
else if (label.equals("Capture")) {
video = new Video(this);
video.start();
form.addCommand(send);
form.removeCommand(camera);
}
else if( label.equalsIgnoreCase("Send") ){
try {
startSendOperation();
} catch (Exception ex) {
}
}
}
public boolean uploadImage( String uri, byte[] rawImage)throws Exception
{
HttpConnection httpConnection;
OutputStream out;
// Open connection to the script
httpConnection = (HttpConnection)Connector.open( uri );
// Setup the request as an HTTP POST and encode with form data
httpConnection.setRequestMethod( HttpConnection.POST );
httpConnection.setRequestProperty( "Content-type", "application/
x-www-form-urlencoded" );
// Encode the imagedata with Base64
String encoded = Base64.encode( rawImage ).toString();
// Build the output and encoded string
String output = "imgdata=" + encoded;
// Set the content length header
httpConnection.setRequestProperty("Content-Length", Integer.toString
((output.getBytes().length)));
// Open the output stream and publish data
out = httpConnection.openOutputStream();
out.write( output.getBytes() );
// Flush the buffer (might not be necessary?)
out.flush();
// Here you might want to read a response from the POST to make
// sure everything went OK.
// Close everything down
if( out != null )
if( httpConnection != null )
httpConnection.close();
// All good
return true;
}
public void startSendOperation() throws Exception{
boolean res = uploadImage( "http://www.xxx.com/postFolder?", localData);
}
public void showCamera(){
try{
player = Manager.createPlayer("capture://video");
player.realize();
videoControl = (VideoControl)player.getControl("VideoControl");
Canvas canvas = new VideoCanvas(this, videoControl);
canvas.addCommand(back);
canvas.addCommand(capture);
canvas.setCommandListener(this);
display.setCurrent(canvas);
player.start();
} catch (IOException ioe) {} catch (MediaException me) {}
}
class Video extends Thread {
myMidlet midlet;
public Video(myMidlet midlet) {
this.midlet = midlet;
}
public void run() {
captureVideo();
}
public void captureVideo() {
try {
byte[] photo = videoControl.getSnapshot(null);
localData = photo;
Image image = Image.createImage(photo, 0, photo.length);
form.append(image);
display.setCurrent(form);
player.close();
player = null;
videoControl = null;
} catch (MediaException me) { }
}
};
}
class VideoCanvas extends Canvas {
private myMidlet midlet;
public VideoCanvas(myMidlet midlet, VideoControl videoControl) {
int width = getWidth();
int height = getHeight();
this.midlet = midlet;
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
try {
videoControl.setDisplayLocation(2, 2);
videoControl.setDisplaySize(width - 4, height - 4);
} catch (MediaException me) {}
videoControl.setVisible(true);
}
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
g.setColor(255, 0, 0);
g.drawRect(0, 0, width - 1, height - 1);
g.drawRect(1, 1, width - 3, height - 3);
}
}
In ShowCamera method,Instead of
Manager.createPlayer("capture://video");
Try using
Manager.createPlayer("capture://image");