Rich Faces consists of some really useful components that can be used to make as they say some very "rich web applications".
In this tutorial i will be explaining about how to use richfaces file upload component to store a file into the database and then retrieve the file using a Jersey restful web service.
The file upload component of rich faces supports two modes of uploading.
- To store the uploaded file in a temporary directory or
- To keep an in memory representation of it.
If you want to create temp files then specify the following filter initialization parameter in the web.xml file.
<init-param>
<param-name>createTempFiles</param-name>
<param-value>true</param-value>
</init-param>
But we are going to set it to false.
Following is the filter configuration for richfaces
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>ruby</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
<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>10000000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
The relevant code for jsp file is listed below.
<h:form enctype="multipart/form-data">
....
<h:panelGrid columns="2" columnClasses="top,top">
<rich:fileUpload fileUploadListener="#{fileUpload.listener}"
maxFilesQuantity="#{fileUpload.uploadsAvailable}"
id="upload"
immediateUpload="#{fileUpload.autoUpload}"
allowFlash="#{fileUpload.useFlash}">
<a4j:support event="onuploadcomplete" reRender="info" />
</rich:fileUpload>
<h:panelGroup id="info">
<rich:panel bodyClass="info">
<f:facet name="header">
<h:outputText value="Uploaded Files Info" />
</f:facet>
<h:outputText value="No files currently uploaded"
rendered="#{fileUpload.size==0}" />
<rich:dataGrid columns="1" value="#{fileUpload.files}"
var="file" rowKeyVar="row">
<rich:panel bodyClass="rich-laguna-panel-no-header">
<h:panelGrid columns="2">
<a4j:mediaOutput element="img" mimeType="#{file.mime}"
createContent="#{fileUpload.paint}" value="#{row}"
style="width:100px; height:100px;" cacheable="false">
<f:param value="#{fileUpload.timeStamp}" name="time"/>
</a4j:mediaOutput>
<h:panelGrid columns="2">
<h:outputText value="File Name:" />
<h:outputText value="#{file.name}" />
<h:outputText value="File Length(bytes):" />
<h:outputText value="#{file.length}" />
</h:panelGrid>
</h:panelGrid>
</rich:panel>
</rich:dataGrid>
</rich:panel>
<rich:spacer height="3"/>
<br />
<a4j:commandButton action="#{fileUpload.clearUploadData}"
reRender="info, upload" value="Clear Uploaded Data"
rendered="#{fileUpload.size>0}" />
</h:panelGroup>
</h:panelGrid>
</h:form>
The code for the fileUpload backing bean is mentioned below.
In the code below all the parameters are passed to the DAO class directly i recommend that you use a DTO and pass it instead.
public class FileUploadBacking {
private ArrayList<filevo> files = new ArrayList<filevo>();
private int uploadsAvailable = 10;
private boolean autoUpload = false;
private boolean useFlash = false;
public int getSize() {
if (getFiles().size() > 0) {
return getFiles().size();
} else {
return 0;
}
}
//used to write in the display pane
public void paint(OutputStream stream, Object object) throws IOException {
stream.write(getFiles().get((Integer) object).getData());
}
public void listener(UploadEvent event) throws Exception {
UploadItem item = event.getUploadItem();
FileStoreDAO fdao=FileStoreDAO.getInstance();
FacesContext fctx=FacesContext.getCurrentInstance();
HttpServletRequest request=(HttpServletRequest)fctx.getExternalContext().getRequest();
HttpSession session=request.getSession();
// Call the storeFile method of fileStoreDAO passing it the params. //Create a DTO for such calls
String result=fdao.storeFile(item.getData(),item.getFileName(),item.getContentType(),session.getAttribute("userID").toString());
if(result.equalsIgnoreCase("success"))
{
FileVO fileVO = new FileVO();
fileVO.setName("your application domain"+" context root"+"rest resource mapping"+item.getFileName());
fileVO.setLength(item.getData().length);
fileVO.setData(item.getData());
else{
FacesMessage fmsg=new FacesMessage(FacesMessage.SEVERITY_ERROR,"Db error","Some Db error has occured could not upload your files");
fctx.addMessage(null, fmsg);
}
files.add(fileVO);
uploadsAvailable--;
}
//clear the data
public String clearUploadData() {
for(int i=0;i<files.size();i++){
FileStoreDAO fdao=FileStoreDAO.getInstance();
fdao.removeData(files.get(i).getFileName());
}
files.clear();
return "success";
}
//rest of the code
The DAO class for storing,reading or updating files is listed below:-
public class FileStoreDAO {
private FileStoreDAO(){
}
public static FileStoreDAO getInstance(){
return new FileStoreDAO();
}
public void removeData(String fileName){
DBConnection conn = null;
PreparedStatement pstmt = null;
Statement stmt=null;
try{
conn = new DBConnection();
stmt = conn.getStatement();
stmt.executeUpdate("delete from file_store where file_name like '"+fileName+"'");
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (stmt != null) {
stmt.close();
}
conn.closeConnection();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
public String storeFile(byte data[],String fileName,String fileType,String userID){
DBConnection conn = null;
PreparedStatement pstmt = null;
Statement stmt=null;
ResultSet rs = null;
String outcome;
boolean flag=false;
try{
conn = new DBConnection();
stmt = conn.getStatement();
ByteArrayInputStream bis=new ByteArrayInputStream(data);
rs=stmt.executeQuery("Select count(*) from file_store where file_name like '"+fileName+"'");
if(rs.next()){
if(rs.getInt(1)>0){
flag=true;
}
}
rs=null;
if(flag){
pstmt=conn.getPreparedStatement("update file_store set file_data=? , file_type=? , user_id=? , file_size=? , mod_date=sysdate() where file_name like ?" );
pstmt.setAsciiStream(1,(InputStream)bis,data.length);
pstmt.setString(2,fileType);
pstmt.setString(3,userID);
pstmt.setLong(4,data.length);
pstmt.setString(5,"'"+fileName+"'");
pstmt.executeUpdate();
}
else{
pstmt = conn.getPrepareStatement("Insert into file_store (file_name,file_data,file_type,user_id,file_size,mod_date) values (?,?,?,?,?,sysdate())");
pstmt.setString(1,fileName);
pstmt.setAsciiStream(2,(InputStream)bis,data.length);
pstmt.setString(3,fileType);
pstmt.setString(4,userID);
pstmt.setLong(5,data.length);
pstmt.executeUpdate();
System.out.println("After insert");
}
}
catch (Exception e) {
e.printStackTrace();
outcome="failure";
}
finally {
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (stmt != null) {
stmt.close();
}
conn.closeConnection();
} catch (Exception e1) {
e1.printStackTrace();
}
}
outcome="success";
return outcome;
}
public FileDTO readFile(String fileName){
DBConnection conn = null;
Statement stmt = null;
ResultSet rs = null;
FileDTO fileDTO=new FileDTO();
try {
conn = new DBConnection();
String query="Select file_name,file_type,file_size,file_data from file_store where file_name=?";
pstmt = conn.getPrepardedStatement(query);
pstmt.setString(1,"'"+fileName +"'");
rs=stmt.executeQuery();
if(rs.next()){
fileDTO.setFileData(rs.getAsciiStream("file_data"));
fileDTO.setMime(rs.getString("file_type"));
fileDTO.setLength(rs.getLong("file_size"));
fileDTO.setFileName(rs.getString("file_name"));
}
}
catch (Exception e) {
fileDTO=null;
e.printStackTrace();
}
finally {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
conn.closeConnection();
} catch (Exception e1) {
e1.printStackTrace();
}
}
return fileDTO;
}
}
Now all we have to do is write the code of the jersey based restful web service and configure the jersey servlet.
The jersey servlet configuration is shown below:-
<servlet>The jersey servlet intercepts any call to the resource under /rest.
<servlet-name>JerseyWebService</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
com.blogspot.ramannanda.editor.rest
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyWebService</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
The code for the resource class is shown below.
@Path("/")The FileResouce class has a mapping of /files/{filename} specified where filename is the path parameter. For example if a call to http://your-domain/yourcontextroot/rest/files/abc.jpg comes the method annotated with the get annotation simply call's the DAO class's readFile method passing it the file name as abc.jpg and get the data as a stream(if the file exists), The method then builds a response and returns it to the client.
public class FileResource {
/**
* @param filename passed in the get request
* @returns builds and returns the response
*
**/
@GET
@Path("/files/{filename}")
@Produces(MediaType.WILDCARD)
public Response returnFileAsStream(@PathParam("filename") String fileName){
FileStoreDAO ftDAO=FileStoreDAO.getInstance();
FileDTO fdto=ftDAO.readFile(fileName);
if(fdto!=null){
String contentType=fdto.getMime();
InputStream is=fdto.getFileData();
return Response.ok(is,contentType).build();
}
else
{
return Response.noContent().build();
}
}
}
Hope this tutorial was helpful
No comments:
Post a Comment