Problems with file upload
donakalz Mar 12, 2010 4:16 AMHi,
I have a minor or major issue depending on how you choose to look at it. On my app, i have file upload functionality. Everything works fine with the uploads, no errors whatsoever. My uploaded images are stored in BLOBs in a database. The issue arises when I retrieve these blobs and try to display them on the page. There are no errors but the images do not show up! I have tried various things and it seems there is a slight correlation between how big the image is and if it is able to get displayed on the page. So far, only very very small images show up on the page (sometimes) while the larger ones never get showed. Below is my code.
Web.xml
<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
<init-param>
<param-name>createTempFiles</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>maxRequestSize</param-name>
<param-value>1048576</param-value>
</init-param>
</filter>
My Photo Entity Bean:
@Entity
@Table(name="Photos")
@Name("photo")
@Scope(ScopeType.SESSION)
public class Photo implements Serializable {
private static final long serialVersionUID = 5764974061144989689L;
private Long id;
private Integer version;
private String caption;
private Date modified;
private String mimeType;
private Integer fileSize;
private byte[] content;
private User user;
public Photo(){
}
@Id
@GeneratedValue
@Column(name="photo_id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Version
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public String getCaption() {
return caption;
}
public void setCaption(String caption) {
this.caption = caption;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public void setFileSize(Integer fileSize) {
this.fileSize = fileSize;
}
public Integer getFileSize() {
return fileSize;
}
public String getMimeType() {
return mimeType;
}
@Lob
@Basic(optional=false, fetch=FetchType.LAZY)
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="user_id")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
My Facelets Page (sections for uploading and displaying the uploaded images)
<h:panelGrid rows="2" rowClasses="rich-fileupload-list-decor , rich-fileupload-list-decor" >
<rich:fileUpload fileUploadListener="#{photoUpload.uploadListener}"
maxFilesQuantity="#{photoUpload.uploadsAvailable}"
id="upload"
immediateUpload="#{photoUpload.autoUpload}"
acceptedTypes="#{photoUpload.acceptedTypes}" allowFlash="#{photoUpload.useFlash}">
<a4j:support event="onuploadcomplete" reRender="picpanel" />
</rich:fileUpload>
<rich:panel style="width: 935px; height: 100%; vertical-align: top;" id="picpanel">
<f:facet name="header">
<h:outputText value="Uploaded Photos" />
</f:facet>
<h:outputText value="No files currently uploaded"
rendered="#{photoUpload.size == 0}" />
<rich:dataGrid columns="1" value="#{photoUpload.files}"
var="photo" rowKeyVar="row" elements="10" id="picdata" style="width: 910px;">
<rich:panel style="width: 900px; height: 80px">
<h:panelGrid columns="2">
<a4j:mediaOutput element="img" mimeType="#{photo.mimeType}"
createContent="#{photoUpload.paintPhoto}" value="#{photo}"
style="width:60px; height:60px;" cacheable="true" session="true" />
<h:panelGrid columns="2">
<h:outputText value="File Name:" />
<h:outputText value="#{photo.caption}" />
<h:outputText value="Photo Size:" />
<h:outputText value="#{photo.fileSize} bytes" />
</h:panelGrid>
</h:panelGrid>
</rich:panel>
<f:facet name="footer" rendered="#{photoUpload.size > 0}">
<rich:datascroller rendered="#{photoUpload.size > 0}"/>
</f:facet>
</rich:dataGrid>
</rich:panel>
</h:panelGrid>
My Stateful Session Bean which handles the uploads
@Stateful
@Name("photoUpload")
@Synchronized( timeout=1000000000)
@Scope(ScopeType.SESSION)
public class PhotoUploadBean implements PhotoUpload, Serializable {
private static final long serialVersionUID = 1627470298195374254L;
@Logger
private Log log;
@PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager em;
@In(required = true, scope = ScopeType.SESSION)
@Out(scope = ScopeType.SESSION)
User currentUser;
private List<Photo> files = new ArrayList<Photo>();
private int uploadsAvailable = 10;
private boolean autoUpload = false;
private boolean useFlash = false;
private String acceptedTypes = "jpg, gif, png, bmp";
public List<Photo> getFiles() {
return files;
}
public void setFiles(List<Photo> files) {
this.files = files;
}
public int getUploadsAvailable() {
return uploadsAvailable;
}
public void setUploadsAvailable(int uploadsAvailable) {
this.uploadsAvailable = uploadsAvailable;
}
public boolean getAutoUpload() {
return autoUpload;
}
public void setAutoUpload(boolean autoUpload) {
this.autoUpload = autoUpload;
}
public boolean getUseFlash() {
return useFlash;
}
public void setUseFlash(boolean useFlash) {
this.useFlash = useFlash;
}
public String getAcceptedTypes() {
return acceptedTypes;
}
public void setAcceptedTypes(String acceptedTypes) {
this.acceptedTypes = acceptedTypes;
}
public int getSize() {
if (getFiles().size() > 0) {
return getFiles().size();
} else {
return 0;
}
}
public PhotoUploadBean() {
}
public void paintPhoto(OutputStream stream, Object object) {
log.info( "paintPhoto() called");
boolean rescale = false;
int width = 0;
ImageIcon icon = null;
byte[] data = null;
try {
// check if image needs to be resized
data = ((Photo) object).getContent();
icon = new ImageIcon(data);
width = icon.getIconWidth();
if ( width > 50 ) {
width = 50;
rescale = true;
}
// rescale if required
if (rescale) {
double ratio = (double) width / icon.getIconWidth();
int height = (int) ( icon.getIconHeight() * ratio );
int imageType = BufferedImage.TYPE_INT_ARGB;
BufferedImage bufferedImage = new BufferedImage(width, height, imageType);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.drawImage(icon.getImage(), 0, 0, width, height, null);
g2d.dispose();
String formatName = "png";
ImageIO.write( bufferedImage, formatName, stream);
} else {
stream.write(data);
}
} catch (IOException e) {
log.error("I/O exception occurred while generating photo");
}
}
public void uploadListener(UploadEvent event) {
UploadItem item = event.getUploadItem();
Photo newPhoto = new Photo();
try {
if (item != null) {
newPhoto = new Photo();
newPhoto.setCaption(item.getFileName());
newPhoto.setContent(item.getData());
newPhoto.setModified(new Date());
newPhoto.setMimeType(item.getContentType());
newPhoto.setFileSize(item.getFileSize());
newPhoto.setUser(currentUser);
em.persist(newPhoto);
files.add(newPhoto);
uploadsAvailable--;
em.flush();
}
} catch (Exception e) {
log.info("error: " + e.getMessage());
}
}
@Create
public void init() {
log.info("Bean Initialized");
}
@Destroy
@Remove
public void destroy() {
log.info("Bean Destroyed");
}
}
Please any help would be greatly appreciated! Thanks.
Charles.