inserting an image in the database with a BLOB datatype - mysql

entity:
#Lob
#Column(name = "logo")
private byte[] logo;
form:
<h:form enctype="multipart/form-data">
<p:messages showDetail="true"/>
<p:fileUpload value="#{testController.file}"
update="messages"
mode="simple"
sizeLimit="1048576"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:growl id="messages" showDetail="true"/>
<p:commandButton value="Submit" ajax="false"
actionListener="#{testController.upload}"/>
</h:form>
bean:
private testEntity current;
private UploadedFile file;
public UploadedFile getFile() {
return file;
}
public void upload() {
if (file != null) {
try {
byte[] data = file.getContents();
current.setLogo(data);
getFacade().edit(current);
JsfUtil.addSuccessMessage("Successful! " + file.getFileName() + " is uploaded.");
} catch (Exception e) {
}
}
}
when i try to upload files like 80kb picture, it will give me this exception
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'logo' at row 1
but if i upload a mere < 10kb pictures, the code works.
using JSF 2.0, Primefaces 3.5, most codes are auto generated using CRUD.

The problem is that your database column is set to stored less than what you are trying to store. That's what truncating means.
You will need to change your database column definition to LONGBLOB.

Related

Primefaces p:media PDF not loading

When I try to load my page including a primefaces media pdf the PDF is not loaded.
I generate the PDF in my postconstruct and keep the streamedcontent in a seperate variable.
In my JSF I call the getStream method that returns the streamedcontent.
JSF page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/templates/header.xhtml">
<ui:define name="content">
<f:metadata>
<f:viewParam name="invoiceID" value="#{invoiceBean.invoiceID}"/>
</f:metadata>
<ui:param name="invoiceID" value="#{invoiceBean.invoiceID}"/>
<h4 style="text-align: center;"><h:outputText
value="#{msgs['invoice.thankYou']}"/></h4>
<div class="card">
<p:media value="#{invoiceBean.stream}" player="pdf" width="100%" height="800px">
Your browser can't display pdf,
<h:outputLink
value="#{invoiceBean.streamedContent}">click
</h:outputLink>
to download pdf instead.
</p:media>
</div>
</ui:define>
</ui:composition>
</html>
Bean:
#Model
#Getter
#Setter
public class InvoiceBean {
#Inject
InvoiceService invoiceService;
#Inject
HttpServletRequest httpServletRequest;
private Invoice invoice;
private String invoiceID;
private StreamedContent streamedContent;
#PostConstruct
public void initInvoice() {
User user = getLoggedInUser();
invoiceID = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("invoiceID");
invoice = invoiceService.getInvoice(Long.parseLong(invoiceID));
PDFGenerator pdf = new PDFGenerator(invoice);
streamedContent = pdf.getStreamedContent();
}
public StreamedContent getStream() throws IOException{
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
return streamedContent;
}
}
}
Because the stream is dynamic, this post from #BalusC is very useful to resolve this issue. In particular "never declare StreamedContent nor any InputStream or even UploadedFile as a bean property; only create it brand-new in the getter of a stateless #ApplicationScoped bean when the webbrowser actually requests the image content."
The p:media tag needs to disable the cache.
<p:media value="#{pdfViewController.pdf}" player="pdf" cache="false"
width="100%" height="500px" >
Your browser can't display pdf.
</p:media>
<br/>
<h:form>
<p:commandButton value="Download" icon="pi pi-arrow-down" ajax="false">
<p:fileDownload value="#{pdfViewController.pdfDownload}" />
</p:commandButton>
</h:form>
The backing bean needs to do all the work in the getter, not in the PostConstruct method. (See the comments in #BalusC's post about this.) I was able to use both Request (per Showcase) and Session beans, but the PrimeFaces documentation warns against ViewScoped.
#Named
#RequestScoped
public class PdfViewController implements java.io.Serializable {
public StreamedContent getPdf() {
return DefaultStreamedContent.builder()
.contentType("application/pdf")
.stream(() -> makePDFStream())
.build();
}
protected ByteArrayInputStream makePDFStream() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String dt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss-n"));
makePDF(baos, "This message was created at " + dt);
return new ByteArrayInputStream(baos.toByteArray());
}
// use iText to create a PDF document "on the fly"
protected void makePDF(OutputStream os, String message) {
PdfDocument pdf = new PdfDocument(new PdfWriter(os));
try (Document document = new Document(pdf)) {
String line = "Hello! Welcome to iTextPdf";
document.add(new Paragraph(line));
document.add(new LineSeparator((new SolidLine())));
PdfFont font = PdfFontFactory.createFont(StandardFonts.TIMES_ITALIC);
Text msgText = new Text(message).setFont(font).setFontSize(10);
document.add(new Paragraph().add(msgText));
} catch (IOException ex) {
LOG.log(Level.SEVERE, "PDF document creation error", ex);
}
// os is automatically written and closed when document is autoclosed
}
}
In order to support the download option and because the bean is #request, the stream is recreated when needed. It was also necessary to include the .name("...)", whereas the p:media value= tag failed if name is specified, hence it needs a separate method.
public StreamedContent getPdfDownload() {
return DefaultStreamedContent.builder()
.name("temp.pdf")
.contentType("application/pdf")
.stream(() -> makePDFStream())
.build();
}
Tested with PrimeFaces v8 and Wildfly v21 (w/Mojarra).

RowKey of DataTable is null when calling onCellEdit

I have a Primefaces 6.0 DataTable working with a LazyDataModel bean. After I changed to the lazy implementation, the cell edition stopped working.
The reason for that is whenever I call my onCellEdit method, and try to get the clicked row contents by calling event.getRowkey() , I get a null object.
As per Primefaces Documentation I'm have a rowKey attribute to bind the tuple with the bean value, but it doesn't seems to work.
EDIT: I can update the value now, but the dataTable doesn't reload the cell UiElement. To see the changes i have to F5 the page.
Here is my ata.xhtml DATATABLE(Sanitized)
<p:tabView id="tab" value="#{setorMB.listaSetor}" var="tabView"
activeIndex="#{ataGerencialMB.activeTabIndex}">
<p:ajax event="tabChange" listener="#{ataGerencialMB.onTabChange}"
update="tab ,formListagemCapacitacao" />
<p:tab title="#{tabView.sigla}">
<p:dataTable id="dtCapacitacao"
value="#{ataGerencialMB.lazyModelAtaGerencial}"
var="gerencial"
lazy="true"
paginator="true"
rows="#{Config.NUM_ROWS}"
currentPageReportTemplate="#{Config.CURRENT_PAGE_REPORT_TEMPLATE}"
paginatorTemplate="#{Config.PAGINATOR_TEMPLATE}"
rowsPerPageTemplate="#{Config.ROWS_PER_PAGE_TEMPLATE}"
sortBy="#{gerencial.idAta}"
sortOrder="ascending"
reflow="true"
editable="true"
editMode="cell"
rowKey="#{gerencial.idAta}">
<p:ajax event="cellEdit"
listener="#{ataGerencialMB.onCellEdit}" oncomplete="onCellEdit()"/>
<p:column>
<p:rowToggler/>
</p:column>
<p:column headerText="Tipo Assunto" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{gerencial.tipo}"
rendered="true" />
</f:facet>
<f:facet name="input">
<p:inputTextarea id="tipo"
value="#{gerencial.tipo}"
style="width:96%" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
Class that extends the LazyDataModel AtaGerencialLazyDataModel
public class AtaGerencialLazyDataModel extends LazyDataModel<AtaGerencialBean> {
AtaGerencialBusiness ataBusiness = new AtaGerencialBusiness();
Map<String, Object> customFilters = new HashMap<String, Object>();
private List<AtaGerencialBean> listaAtaGerencialBean = new ArrayList<AtaGerencialBean>();
public AtaGerencialLazyDataModel(){
this.setRowCount(ataBusiness.getAtaGerencialTotalCount(null));
}
public AtaGerencialLazyDataModel(SetorBean setor){
customFilters.put("setor", setor);
this.setRowCount(ataBusiness.getAtaGerencialTotalCount(customFilters));
}
#Override
public List<AtaGerencialBean> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> filters){
List<AtaGerencialBean> list = ataBusiness.fetchLazyAtaGerencial(first, pageSize, sortField, sortOrder, customFilters);
this.setRowCount(ataBusiness.getAtaGerencialTotalCount(customFilters));
setListaAtaGerencialBean(list);
setWrappedData(list);
return list;
}
#Override
public AtaGerencialBean getRowData(String rowKey){
try{
long id = Long.parseLong(rowKey);
for (AtaGerencialBean bean : listaAtaGerencialBean) {
if (bean.getIdAta() == id){
return bean;
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
return null;
}
#Override
public Object getRowKey(AtaGerencialBean p) {
return p.getIdAta();
}
public List<AtaGerencialBean> getListaAtaGerencialBean() {
return listaAtaGerencialBean;
}
public void setListaAtaGerencialBean(
List<AtaGerencialBean> listaAtaGerencialBean) {
this.listaAtaGerencialBean = listaAtaGerencialBean;
}
}
The onCellEdit method
#ManagedBean
#ViewScoped
public class AtaGerencialMB extends MB<AtaGerencialBean,
AtaGerencialBusiness> {
private LazyDataModel<AtaGerencialBean> lazyModelAtaGerencial;
#SuppressWarnings("unused")
public void onCellEdit(CellEditEvent event) {
try{
DataTable controladorTabela = (DataTable) event.getComponent();
//rowindex is fine, it brings the index of the edited row in the
datatable (from 0 onwards)
Integer rowIndex = event.getRowIndex();
String rowKey = event.getRowKey();
//rowKey is always null
System.out.println("rowKey value:" + rowKey);
AtaGerencialBean entity = (AtaGerencialBean) controladorTabela.getRowData(event.getRowKey());
this.setRegistroDefinido(entity);
super.atualizar();
}catch(NullPointerException ex){
System.out.println(ex.getMessage());
}
}
}
EDIT
I was able to circumvent the problem by NOT using the rowKey to retrieve the data and modifying the onCellEdit method to get the data from the Datamodel inside the Datatable.
I am not sure whether it is a good/bad practice, or if that's how you're supposed to retrieve the row when using LazyLoading.
Also, following #Kukeltje suggestion, I am now using PRIMEFACES 6.2
Modified onCellEdit method
#ManagedBean
#ViewScoped
public class AtaGerencialMB extends MB<AtaGerencialBean, AtaGerencialBusiness> {
private LazyDataModel<AtaGerencialBean> lazyModelAtaGerencial;
#SuppressWarnings("unused")
public void onCellEdit(CellEditEvent event) {
try{
DataTable controladorTabela = (DataTable) event.getComponent();
DataModel dm = (DataModel) controladorTabela.getValue();
AtaGerencialBean entity = (AtaGerencialBean) dm.getRowData();
this.setRegistroDefinido(entity);
super.atualizar();
}catch(NullPointerException ex){
System.out.println(ex.getMessage());
}
}
}
I was able to circumvent the problem by NOT using the rowKey to retrieve the data and modifying the onCellEdit method to get the data from the Datamodel inside the Datatable.
I am not sure whether it is a good/bad practice, or if that's how you're supposed to retrieve the row when using LazyLoading.
Also, following #Kukeltje suggestion, I am now using PRIMEFACES 6.2
Modified onCellEdit method
#SuppressWarnings("unused")
public void onCellEdit(CellEditEvent event) {
try{
DataTable controladorTabela = (DataTable) event.getComponent();
DataModel dm = (DataModel) controladorTabela.getValue();
AtaGerencialBean entity = (AtaGerencialBean) dm.getRowData();
this.setRegistroDefinido(entity);
super.atualizar();
}catch(NullPointerException ex){
System.out.println(ex.getMessage());
}
}
https://github.com/primefaces/primefaces/issues/2688
You may refer to this issue on github. You should enable selection for your datatable

liveScroll appended page refresh on selecting row Primefaces dataTable

I think i found a bug with livescroll in dataTable in Primefaces 6.1.
I have command link in second column that is saving row/rownumber to variables and calling method to save a file. It works on first 10 elements (size of page), but dont work on any other element that is appended by live pagination - instead something happens to invoke load with first set to 0. I dont see any errors in browser console or tomcat console. On my main project also page is losing all css elements, only text stays, but it could be liferay 6.2 issue.
If i disable liveScroll by replacing
scrollRows="10" liveScroll="true" scrollHeight="90%" scrollable="true"
with
paginatorTemplate="{PreviousPageLink} {NextPageLink}" paginator="true"
everything works. I have run out of ideas how to debug and fix it, any suggestions?
xhtml datatable:
<p:dataTable var="live" value="#{LiveLazyModel}" rows="10" lazy="true"
scrollRows="10" liveScroll="true" scrollHeight="90%" scrollable="true"
style="width: 1000px">
<p:column headerText="Id">
<h:outputText value="#{live.id}" id="idlive"/>
</p:column>
<p:column headerText=".txt" style="width: 80px" exportable="false">
<h:commandLink>
<h:outputText value="download"/>
<f:param name="liveId" value="#{live.id}" />
<f:setPropertyActionListener value="#{live}" target="#{LiveLazyModel.selectedRow}"/>
<p:fileDownload value="#{LiveLazyModel.liveStreamedContent}"/>
</h:commandLink>
</p:column>
</p:dataTable>
bean:
#ManagedBean(name = "LiveLazyModel")
#ViewScoped
public class LiveLazyModel extends LazyDataModel {
private Live selectedRow;
#Override
public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) {
List list = addToList(first, pageSize);
this.setRowCount(100);
this.setPageSize(pageSize);
return list;
}
private List addToList(int first, int pageSize) {
List list = new ArrayList();
for (Integer i = first; i < first + pageSize; i++) {
list.add(new Live(i));
}
return list;
}
public StreamedContent getliveStreamedContent() throws IOException {
String idFrom = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("liveId");
if(selectedRow != null){
InputStream targetStream = IOUtils.toInputStream(selectedRow.id + (Double.toString(Math.random()).substring(1)));
return new DefaultStreamedContent(targetStream, "txt", "idLiveFromSelectedRow" + selectedRow.id + ".txt");
}
if (idFrom != null) {
InputStream targetStream = IOUtils.toInputStream(idFrom + (Double.toString(Math.random()).substring(1)));
return new DefaultStreamedContent(targetStream, "txt", "idLiveFromFacesContext" + idFrom + ".txt");
}
throw new RuntimeException("liveId is null & selectedRow is null ");
}
public void setSelectedRow(Live selectedRow) {
this.selectedRow = selectedRow;
}
}
Working barebone code could be found on:
https://github.com/TomaszKocinski/jsfPFLiveScrollBugPagination
to run it: mvn tomcat7:run should be enough, localhost:9966/live

PrimeFaces add row to DataTable

I want to make a Log-File-Reader. I have a Upload field, and a dataTable. First I choose the Log-File an Upload it. Then the program Split each line of the Log-File in the separate variables. Now the Log-File should be printet line for line into the table. But I dont know, how i should put the Lines in the Table. It works, when I define the Lines Static bevore. But now when the lines are not defined static it don't update the Table.
Here is my index.xhtml:
<h:form xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>LogReader</title>
</h:head>
<h:body>
<p:accordionPanel dynamic="true" cache="true" activeIndex="1" multiple="false">
<p:tab title="Upload File">
<h:panelGrid>
<p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}" mode="advanced" dragDropSupport="false"
update="messages" fileLimit="1" allowTypes="/(\.|\/)(log|txt|)$/" />
<p:growl id="messages" showDetail="true"/>
</h:panelGrid>
</p:tab>
</p:accordionPanel>
<p:dataTable id="dataTable" var="log" value="#{fileUpload.logsSmall}" widgetVar="dataTable"
emptyMessage="No Log found with given criteria" filteredValue="#{tableBean.filteredLogs}"
rowKey="#{log.datetime}" paginator="true" rows="20" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15,20,50,100" selection="#{tableBean.selectedLog}" selectionMode="single">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="dataTable.filter();" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column id="datetimeColumn" filterBy="datetime" sortBy="datetime"
headerText="DateTime" footerText=""
filterMatchMode="contains">
<h:outputText value="#{log.datetime}" />
</p:column>
<p:column id="levelColumn" filterBy="level"
headerText="LogLevel" footerText=""
filterOptions="#{tableBean.levelOptions}"
filterMatchMode="exact" sortBy="level">
<h:outputText value="#{log.level}" />
</p:column>
<p:column id="categoryColumn" filterBy="category" sortBy="category"
headerText="Category" footerText=""
filterMatchMode="contains">
<h:outputText value="#{log.category}" />
</p:column>
<p:column id="messageColumn" filterBy="message" sortBy="message"
headerText="Message" footerText="" filterMatchMode="contains">
<h:outputText value="#{log.message}" />
</p:column>
</p:dataTable>
</h:body>
Here my TableBean:
package com.rausch.logreader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import com.rausch.logreader.Log;
#ViewScoped
#ManagedBean(name = "tableBean")
#SessionScoped
public class TableBean implements Serializable {
private final static String[] level;
private SelectItem[] levelOptions;
private List<Log> filteredLogs;
private int i = 0;
private Log selectedLog;
private Log[] selectedLogs;
static {
level = new String[5];
level[0] = "DEBUG";
level[1] = "INFO";
level[2] = "WARN";
level[3] = "ERROR";
level[4] = "FATAL";
}
public TableBean() {
levelOptions = createLevelOptions(level);
}
public Log getSelectedLog() {
return selectedLog;
}
public void setSelectedLog(Log selectedLog) {
this.selectedLog = selectedLog;
}
public void listAdd(List<Log> list, String datetime, String level, String category, String message){
list.add(new Log(datetime, level, category, message));
}
public List<Log> getFilteredLogs() {
return filteredLogs;
}
public void setFilteredLogs(List<Log> filteredCars) {
this.filteredLogs = filteredCars;
}
private SelectItem[] createLevelOptions(String[] data) {
SelectItem[] options = new SelectItem[data.length + 1];
options[0] = new SelectItem("", "Select");
for(int i = 0; i < data.length; i++) {
options[i + 1] = new SelectItem(data[i], data[i]);
}
return options;
}
public SelectItem[] getLevelOptions() {
return levelOptions;
}
}
And here my FileUploadController:
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
#ViewScoped
#ManagedBean(name = "fileUploadController")
#SessionScoped
public class FileUploadController {
public List<Log> logsSmall;
public void handleFileUpload(FileUploadEvent event) {
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
e.printStackTrace();
}
}
private String destination="C:\\Java\\";
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName));
int read;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
readFile(destination + fileName);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public void readFile(String filePath){
try
{
String sCurrentLine;
BufferedReader br = new BufferedReader(new FileReader(filePath));
String output;
String datetime = "";
String level = "";
String category = "";
String message;
TableBean table = new TableBean();
while ((sCurrentLine = br.readLine()) != null) {
//System.out.println(sCurrentLine.charAt(4) + "" + sCurrentLine.charAt(7) + sCurrentLine.charAt(13) + "" +sCurrentLine.charAt(16));
if(sCurrentLine.length()<1){
}
else{
if (sCurrentLine.length() >= 16 && sCurrentLine.charAt(4)=='-' && sCurrentLine.charAt(7)=='-' && sCurrentLine.charAt(13)==':' && sCurrentLine.charAt(16)==':'){
output = "";
message = "";
String[] leerzeichen = sCurrentLine.split(" ");
datetime = leerzeichen[0] + " " + leerzeichen[1];
level = leerzeichen[2];
category = leerzeichen[4];
int arraylength = leerzeichen.length;
for (int l=5; l<arraylength; l++){
message = message.concat(leerzeichen[l] + " ");
}
output = datetime + level + category + message;
} else {
message = sCurrentLine;
output = message;
}
logsSmall = new ArrayList<Log>();
table.listAdd(logsSmall, datetime, level, category, message);
System.out.println(output);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sorry for my bad English. I try to Ask an other way:
I want to have a program, where I can upload a *.log File and read it in a table. I open the xhtml, and there is a empty table. Than I Upload the File with the <:pFileUpload. The File Upload Controller takes the Log-File and split each line in the values (datetime, Level, Category and message). Then the Script should add a new row to the table width the datas of the Log-File-Line. Then it goes to the next Line and parses the Text. At the End the Table should show the content of the Log-File.
The Problem is, that the Table don't Reload. Or i don't know how i should reload it. When I upload the File, the script correctly read each Line of the Log-File. But the table keeps empty.
I quite don't understand what is yourt question what i see some lack of understanding on how to use the beans to manage the view.
First, you have #ViewScoped and #SessionScoped declared at the same time. There must be only one.
Second, the thing about defining managed beans it's that you don't have to manage the creation or destruction on them, the system does. Thats why they are called managed. So doing this:
TableBean table = new TableBean();
is useless. You are creating and instance of an object inside a funcion. Outside that function the object is unreacheable, as the annotations aren't considered if you create the object in your code.
I would have one managed bean that handles the events on the view, like this:
#ViewScoped
#ManagedBean(name = "logViewController")
public class LogViewController{
private List<Log> filteredLogs;
private List<Log> logsSmall;
public void handleFileUpload(FileUploadEvent event) {....}
// other private functions
//public getters and setters
}
Also, if you are working with java 7, maybe you want to look at the new file
I/O.

How can i implement upload file in struts2 with hibernate

I m developping a web app ( Electronic Document Managemen) and i need file upload in strurts 2 and store it to mysql using hibernate, can anybody give better idea. advance thanks
Post edited :
I have start with this :
in pojo class i have:
#Entity
#Table(name="Documents")
public class Documents {
#Id
#GeneratedValue
#Column(name="idDocument")
private Integer idDocument;
#Column(name="content")
#Lob
private byte[] content;
#Column(name="description")
private String description;
in class documentsDaoimpl i have :
public class DocumentsDaoImpl implements DocumentsDao{
#SessionTarget
Session session;
#TransactionTarget
Transaction transaction;
#Override
public void saveOrUpdateDocuments(Documents Document) {
try {
session.saveOrUpdate(Document);
} catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}
} .......
In action class i have :
public class DocumentAction extends ActionSupport implements ModelDriven<Documents>{
private Documents document=new Documents();
private DocumentsDao documentdao=new DocumentsDaoImpl();
#Override
public Documents getModel() {
// TODO Auto-generated method stub
return document;
}
public String saveOrUpdate(){
documentdao.saveOrUpdateDocuments(document);
list();
return SUCCESS;
}
.......
And the JSP i have a form :
<s:form action="saveOrUpdateDocuments" method="post">
<s:hidden name="document.idDocument" />
<s:textfield name="document.description" label="document File " required="true" />
<s:file name="document.content" value="Add Document"/>
<s:submit value="upload" />
</s:form>
I don't Know how can i progressed
Are you planning to store files in database as blob type? Declare your column as BLOB type in database and in your model class declare a variable of type byte[].
//userFile is the file submitted from JSP
byte[] bFile = new byte[(int) userFile.length()];
try {
FileInputStream fileInputStream = new FileInputStream(userFile);
//convert file into array of bytes
fileInputStream.read(bFile);
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Now, you can save the bFile into your database. Code taken from this tutorial.
If you simply want to save your image on disk you can follow this code. It also shows how to submit file from JSP using struts 2 form.