i managed to store an image in my mysql database as Blob. (i am also using hibernate)
now i am trying to load that image and send it on a jsp page so the user can view the image.
This is my struts 2 action class
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Blob;
import org.hibernate.Hibernate;
import domain.post.image.Image;
public class FileUploadAction {
private File file;
#SuppressWarnings("deprecation")
public String execute() {
try {
System.out.println(file.getPath());
Image image = new Image();
FileInputStream fi = new FileInputStream(file);
Blob blob = Hibernate.createBlob(fi);
image.setImage(blob);
image.save();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
and this is my Image class
public class Image extends AbsDBObject<Object> {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(Image.class);
private Blob image;
private String description;
//Getters and Setters
}
would you please tell me what should i put in an action class, jsp page and struts.xml in order to showing the stored image?
Finally I solved it, for future googlers :
Add this line to jsp,
<img src="<s:url value="YourImageShowAction" />" border="0"
width="100" height="100">
and this is ShowImageAction class : note that the execute method is void, so no redirection
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.raysep.maxlist.domain.post.image.Image;
public class ShowImageAction {
private static byte[] itemImage;
public static void execute() {
try {
Image slika = Image.fetchOne();
HttpServletResponse response = ServletActionContext.getResponse();
response.reset();
response.setContentType("multipart/form-data");
itemImage = slika.getImage().getBytes(1,(int) slika.getImage().length());
OutputStream out = response.getOutputStream();
out.write(itemImage);
out.flush();
out.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public byte[] getItemImage() {
return itemImage;
}
public void setItemImage(byte[] itemImage) {
this.itemImage = itemImage;
}
}
Related
I am writing some code to collect some controller's request param and response body.
Since the project framework is apache CXF, which version is 3.1.18,
I write an interceptor extends AbstractPhaseInterceptor to collect param in phase Phase.RECEIVE, which is working.
But when a write an outInterceptor extends AbstractPhaseInterceptor to collect the response of the controller, I find there no way for me to do this, there just one method handleMessage(Message message) in the interceptor, I can not fetch anything I want from the message
Can anybody help me? I am new to CXF. Thanks!
I found the answer from the other blob
package XXX.web.webservice.interceptor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<Message>{
private static final Logger log = Logger.getLogger(ArtifactOutInterceptor.class);
public ArtifactOutInterceptor() {
//这儿使用pre_stream,意思为在流关闭之前
super(Phase.PRE_STREAM);
}
public void handleMessage(Message message) {
try {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
InputStream in = csnew.getInputStream();
String xml = IOUtils.toString(in);
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os);
cs.close();
os.flush();
message.setContent(OutputStream.class, os);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : " + "\n" + e);
}
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClose() throws IOException {
}
protected void onWrite() throws IOException {
}
}
}
When downloading bigger (specially videos) files using Spring-boot and java nio package only download part of the file. But smaller files such as images, pdf ect get downloaded properly and usable.
For example : Let say video size is 3.5MB but when downloaded it only show 160KB and cannot play it in any player(that is because, probably partially downloaded)
Following is the controller
package com.filedownloader_with_nio_package.controllers;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.filedownloader_with_nio_package.model.FileDetails;
import com.filedownloader_with_nio_package.services.FileDownloadService;
#RestController
public class FileDownloadController {
#Autowired
FileDownloadService fileDownloadService;
#RequestMapping(method = RequestMethod.POST, value = "/filedownload")
public String downloadFile(#RequestBody FileDetails fileDetails){
return fileDownloadService.downloadFile(fileDetails);
}
}
Following is Service
package com.filedownloader_with_nio_package.services;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import org.springframework.stereotype.Service;
import com.filedownloader_with_nio_package.exceptions.FileNotDownloadedCorrectlyException;
import com.filedownloader_with_nio_package.model.FileDetails;
import com.filedownloader_with_nio_package.utils.Constants;
#Service
public class FileDownloadService {
public String downloadFile(FileDetails fileDetails) {
try {
URL url = new URL(fileDetails.getFileUrl());
ReadableByteChannel readableByteChannel = Channels.newChannel(url
.openStream());
String downloadedFile = fileDetails.getFileDownloadLocation() + "/"
+ fileDetails.getFileName() + "."
+ fileDetails.getFileType();
FileOutputStream fileOutputStream = new FileOutputStream(
downloadedFile);
WritableByteChannel writableByteChannel = fileOutputStream
.getChannel();
//
//
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (readableByteChannel.read(buffer) != -1) {
buffer.flip();
while (buffer.hasRemaining()) {
writableByteChannel.write(buffer);
}
buffer.clear();
}
//
//
fileOutputStream.flush();
fileOutputStream.close();
return downloadedFile;
} catch (MalformedURLException e) {
throw new FileNotDownloadedCorrectlyException(
Constants.FILE_NOT_DOWNLOADED_CORRECTLY, e);
} catch (IOException e) {
throw new FileNotDownloadedCorrectlyException(
Constants.FILE_NOT_DOWNLOADED_CORRECTLY, e);
}
}
}
Following is FileDetails model
package com.filedownloader_with_nio_package.model;
public class FileDetails {
private String fileName;
private String fileUrl;
private String fileType;
private String fileDownloadLocation;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileUrl() {
return fileUrl;
}
public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public String getFileDownloadLocation() {
return fileDownloadLocation;
}
public void setFileDownloadLocation(String fileDownloadLocation) {
this.fileDownloadLocation = fileDownloadLocation;
}
}
This is request body
{
"fileName": "SB2",
"fileUrl": "https://drive.google.com/open?id=1_gkQK8sAlgTslzfRGOvNtbEAwtoPeyJv",
"fileType":"mp4",
"fileDownloadLocation": "C:/DownloadedFiles"
}
I went trough the related questions and answers but I could not find a proper solution for this.
Can any one help to sort out the issue ? or any idea about this welcome.
you need a url with extension to download large files (videos) when using nio packages.
URL url = new URL("https://elpvideo.s3-us-west-2.amazonaws.com/4445/4445.mp4");
If your hosting service provides an API to download files with a particular token then nio packages don't work properly.
URL url = new URL("https://fv2-1.failiem.lv/down.php?i=sk2j3yuya");
tip
if you are downloading a large size of the file then make sure to set timeout if not then it will be disconnected in the middle.
URL url = new URL("https://elpvideo.s3-us-west-2.amazonaws.com/4445/4445.mp4");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout((1000*30)); //30 mins
ReadableByteChannel readableByteChannel = Channels.newChannel(urlConnection.getInputStream());
I'm using Netbeans 7.2 on OS X 10.9. The JFileChooser.showSaveDialog() fails on certain occasions. Before I call the showSaveDialog, I call showOpenDialog to open an .srt file. The show dialog fails only when I open certain files esp. from /Volumes/.. on a mounted device. Here's the code:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.commons.io.FilenameUtils;
public class FileSaver extends JFileChooser {
private int result;
private File subFile;
private File save;
private File filename;
private String rectifiedSub;
private FileNameExtensionFilter filter;
public FileSaver(File subFile, String rectifiedSub) {
this.subFile = subFile;
this.rectifiedSub = rectifiedSub;
filename = new File(System.getProperty("user.home"));
filter = new FileNameExtensionFilter("Subtitle Files (*.srt)", "srt");
}
public void createAndShowGUI() {
System.out.println("6");
this.setDialogTitle("Select destination");
System.out.println("6");
this.setCurrentDirectory(filename);
System.out.println("6");
this.setSelectedFile(new File(subFile.getName()));
System.out.println("6");
this.setFileFilter(filter);
System.out.println("6");
result = this.showSaveDialog(this);
System.out.println("6");
if(result == JFileChooser.APPROVE_OPTION) {
save = fixExtension(this.getSelectedFile());
write(save);
}
this.setVisible(true);
}
public void write(File save) {
FileWriter fw = null;
try {
fw = new FileWriter(save);
fw.write(rectifiedSub);
} catch (IOException ex) {
Logger.getLogger(FileSaver.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
fw.close();
} catch (IOException ex) {
Logger.getLogger(FileSaver.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public File fixExtension(File file) {
if(!FilenameUtils.getExtension(file.getName()).equalsIgnoreCase(".srt"))
file = new File(file.getParentFile(), FilenameUtils.getBaseName(file.getName()).concat(".srt"));
return file;
}
}
Output:
6
6
6
6
6
It stops at the 6 before the line result = this.shhowSaveDialog(this);. The program freezes after that and the save dialog doesn't show up. It works perfectly fine on some files. Somebody tell me whats happening ?
Git: https://github.com/Jimmy-666/Subzero.git
I am trying to append text to a text file on the Google Drive. But when I write, it whole file is overwritten. Why can't I just add the text in the end of the file?
DriveFile file = Drive.DriveApi.getFile(mGoogleApiClient, id);
file.open(mGoogleApiClient, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(new ResultCallback<DriveApi.DriveContentsResult>() {
#Override
public void onResult(DriveApi.DriveContentsResult driveContentsResult) {
msg.Log("ContentsOpenedCallBack");
if (!driveContentsResult.getStatus().isSuccess()) {
Log.i("Tag", "On Connected Error");
return;
}
final DriveContents driveContents = driveContentsResult.getDriveContents();
try {
msg.Log("onWrite");
OutputStream outputStream = driveContents.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.append(et.getText().toString());
writer.close();
driveContents.commit(mGoogleApiClient, null);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Finally I've found the answer to append the text on the drive document.
DriveContents contents = driveContentsResult.getDriveContents();
try {
String input = et.getText().toString();
ParcelFileDescriptor parcelFileDescriptor = contents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor
.getFileDescriptor());
// Read to the end of the file.
fileInputStream.read(new byte[fileInputStream.available()]);
// Append to the file.
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor
.getFileDescriptor());
Writer writer = new OutputStreamWriter(fileOutputStream);
writer.write("\n"+input);
writer.close();
driveContentsResult.getDriveContents().commit(mGoogleApiClient, null);
} catch (IOException e) {
e.printStackTrace();
}
SO
The reason is that commit's default resolution strategy is to overwrite existing files. Check the API docs and see if there is a way to append changes.
For anyone facing this problem in 2017 :
Google has some methods to append data Here's a link!
Though copying the method from google didn't worked entirely for me , so here is the class which would append data : ( Please note this is a modified version of this code link )
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.android.gms.common.api.Result;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.DriveApi.DriveIdResult;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
/**
* An activity to illustrate how to edit contents of a Drive file.
*/
public class EditContentsActivity extends BaseDemoActivity {
private static final String TAG = "EditContentsActivity";
#Override
public void onConnected(Bundle connectionHint) {
super.onConnected(connectionHint);
final ResultCallback<DriveIdResult> idCallback = new ResultCallback<DriveIdResult>() {
#Override
public void onResult(DriveIdResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Cannot find DriveId. Are you authorized to view this file?");
return;
}
DriveId driveId = result.getDriveId();
DriveFile file = driveId.asDriveFile();
new EditContentsAsyncTask(EditContentsActivity.this).execute(file);
}
};
SharedPreferences sp= PreferenceManager.getDefaultSharedPreferences(EditContentsActivity.this);
Drive.DriveApi.fetchDriveId(getGoogleApiClient(), EXISTING_FILE_ID)
.setResultCallback(idCallback);
}
public class EditContentsAsyncTask extends ApiClientAsyncTask<DriveFile, Void, Boolean> {
public EditContentsAsyncTask(Context context) {
super(context);
}
#Override
protected Boolean doInBackgroundConnected(DriveFile... args) {
DriveFile file = args[0];
SharedPreferences sp=PreferenceManager.getDefaultSharedPreferences(EditContentsActivity.this);
System.out.println("0"+sp.getString("drive_id","1"));
DriveContentsResult driveContentsResult=file.open(getGoogleApiClient(), DriveFile.MODE_READ_WRITE, null).await();
System.out.println("1");
if (!driveContentsResult.getStatus().isSuccess()) {
return false;
}
DriveContents driveContents = driveContentsResult.getDriveContents();
try {
System.out.println("2");
ParcelFileDescriptor parcelFileDescriptor = driveContents.getParcelFileDescriptor();
FileInputStream fileInputStream = new FileInputStream(parcelFileDescriptor
.getFileDescriptor());
// Read to the end of the file.
fileInputStream.read(new byte[fileInputStream.available()]);
System.out.println("3");
// Append to the file.
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor
.getFileDescriptor());
Writer writer = new OutputStreamWriter(fileOutputStream);
writer.write("hello world");
writer.close();
System.out.println("4");
driveContents.commit(getGoogleApiClient(), null).await();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
};
#Override
protected void onPostExecute(Boolean result) {
if (!result) {
showMessage("Error while editing contents");
return;
}
showMessage("Successfully edited contents");
}
}
}
Existing_File_id is the resource id. Here is one link if you need resource id a link
I want to use a vaadin upload component in my webapplication and directly upload files to mongo db in gridfs format.
My current implementation use a temporary storage location to first upload file and then store in mongo converting to gridfs.
here is my upload component code: I have implement Receiver interface method recieveUpload
private File file;
private String tempFilePath;
public class HandleUploadImpl extends CustomComponent
implements Upload.SucceededListener,
Upload.FailedListener,
Upload.ProgressListener,
Upload.Receiver { ........
public OutputStream receiveUpload(String filename, String MIMEType) {
logger.debug("File information {} {}", filename, MIMEType);
this.filename = filename;
FileOutputStream fos;
file = new File(tempFilePath + filename);
try {
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
logger.error("Error occurred while opening the file {}", e);
return null;
}
return fos;
}
Here is my code to store in mongo repository
private void saveBuildFile(Map<String, Object> buildFileInfo, String key) {
if (buildFileInfo.containsKey(key)) {
GridFS gridFS = new GridFS(mongoTemplate.getDb(), COLLECTION_NAME);
File file = (File) buildFileInfo.get(key);
buildFileInfo.remove(key);
try {
GridFSInputFile savedFile = gridFS.createFile(file);
savedFile.put(idK, buildFileInfo.get(key + "-id"));
savedFile.save();
} catch (Exception e) {
logger.error("Something went wrong when saving the file in the db {}", e);
}
}
}
Is there a way I can omit the use of temporary storage and set the output stream of upload component to mongo repository gridfs file.
This works for me:
package ch.domain.vaadin;
import ch.domain.vaadin.mongo.MongoItem;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSInputFile;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.ui.Upload.Receiver;
import com.vaadin.ui.Upload.SucceededEvent;
import com.vaadin.ui.Upload.SucceededListener;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
/**
*
* #author eric
*/
class ImageUploader implements Receiver, SucceededListener {
private String filename;
private DB db;
private ByteArrayOutputStream fos;
private FieldGroup fieldGroup;
public void setFieldGroup(FieldGroup fieldGroup) {
this.fieldGroup = fieldGroup;
}
public ImageUploader(DB db)
{
this.db = db;
}
public OutputStream receiveUpload(String filename,
String mimeType) {
// Create upload stream
this.fos = new ByteArrayOutputStream();
this.filename = filename;
return this.fos; // Return the output stream to write to
}
public void uploadSucceeded(SucceededEvent event) {
GridFS gfsPhoto = new GridFS(db, "photo");
GridFSInputFile gfsFile = gfsPhoto.createFile(this.fos.toByteArray());
MongoItem parentId = (MongoItem) fieldGroup.getItemDataSource();
gfsFile.setMetaData(new BasicDBObject().append("parentId", parentId.getItemProperty("_id").getValue().toString()));
gfsFile.setFilename(this.filename);
gfsFile.save();
this.fos = null;
gfsFile = null;
// Show the uploaded file in the image viewer
// image.setVisible(true);
// image.setSource(new FileResource(file));
}
}