Combination View Flat View Tree View
Threads [ Previous | Next ]
Jose Alvarez de Lara
Attached files in an email client portlet, how to
April 4, 2013 8:02 PM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

Hi,

I am trying an email client portlet but need to resolve how to attach several files to my email.
I was wondering in something like,

1
2<h:form id="f3" enctype="multipart/form-data">
3        <h:messages />
4        <h:panelGrid columns="1">
5                <bridge:inputFile fileUploadListener="#{applicantBackingBean.handleFileUpload}" multiple="multiple" />
6        </h:panelGrid>
7        <h:commandButton value="#{i18n['submit']}" />
8</h:form>


being this case the JSF2 implementation of the JSF2 Portlet example (JSF2 Portlet). I am not sure if it is correct but what I pretend is for every file I attach the jsp reload waiting for a new attachment or send the email.

Best regards,
jose
Jose Alvarez de Lara
RE: Attached files in an email client portlet, how to
April 4, 2013 8:28 PM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

At the end I would like to have something like this,

 1
 2<h:form id="f2" enctype="multipart/form-data">
 3    <h:messages globalOnly="true" layout="table" />
 4    <h3>#{i18n['attachments']}</h3>
 5    <h:dataTable headerClass="portlet-section-header results-header"
 6        rowClasses="portlet-section-body results-row, portlet-section-alternate results-row alt"
 7        value="#{applicantModelBean.uploadedFiles}" var="uploadedFile">
 8        <h:column>
 9            <f:facet name="header">
10                <h:outputText value="#{i18n['file-name']}" />
11            </f:facet>
12            <h:outputText value="#{uploadedFile.name}" />
13        </h:column>
14        <h:column>
15            <f:facet name="header">
16                <h:outputText value="#{i18n['size']}" />
17            </f:facet>
18            <h:outputText value="#{uploadedFile.size}" />
19        </h:column>
20    </h:dataTable>
21    <h:panelGrid columns="1">
22        <bridge:inputFile fileUploadListener="#{applicantBackingBean.handleFileUpload}" multiple="multiple" />
23    </h:panelGrid>
24    <h:commandButton value="#{i18n['submit']}" />
25</h:form>
Jose Alvarez de Lara
RE: Attached files in an email client portlet, how to
April 14, 2013 10:55 AM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

This is what I did.

Following the 2012 JSF2 Portlet architecture I have built another webapp that simplify that portlet and add a
new ManagedBean EmailSenderServiceBean in the package com.liferay.faces.demos.bean. Here is my bean,

  1
  2@ManagedBean(name = "emailSenderServiceBean")
  3@ViewScoped
  4public class EmailSenderServiceBean implements Serializable {
  5
  6    private static final long serialVersionUID = -6903026987077945240L;
  7   
  8    private static final Properties properties = new Properties();
  9    private static final String username = "myuser@gmail.com";
 10    private static final String password = "mypass";
 11   
 12    private Session session;
 13    private List<UploadedFile> files;
 14    private String to;
 15    private String subject;
 16    private String messageBodyText;
 17   
 18    private void init() {
 19
 20        properties.put("mail.smtp.host", "smtp.gmail.com");
 21        properties.put("mail.smtp.starttls.enable", "true");
 22        properties.put("mail.smtp.port", 587);
 23        properties.put("mail.smtp.mail.sender","myuser@gmail.com");
 24        properties.put("mail.smtp.user", username);
 25        properties.put("mail.smtp.auth", "true");
 26
 27        session = Session.getDefaultInstance(properties);
 28    }
 29
 30    public void sendEmail(){
 31
 32        init();
 33        try{
 34            
 35            MimeMessage message = new MimeMessage(session);
 36            message.setFrom(new InternetAddress((String)properties.get("mail.smtp.mail.sender")));
 37            message.addRecipient(Message.RecipientType.TO, new InternetAddress(getTo()));
 38            message.setSubject(getSubject());
 39            message.setText(getMessageBodyText());
 40            
 41            if(files.size() > 0) {
 42                Multipart multipart = new MimeMultipart();
 43                for(UploadedFile uf: files) {
 44                    addAttachment(multipart, uf);
 45                }
 46                message.setContent(multipart);
 47            }
 48            
 49            Transport t = session.getTransport("smtp");
 50            t.connect((String)properties.get("mail.smtp.user"), password);
 51            t.sendMessage(message, message.getAllRecipients());
 52            t.close();
 53        }catch (MessagingException me){
 54            me.printStackTrace();
 55            return;
 56        }
 57       
 58    }
 59   
 60    private static void addAttachment(Multipart multipart, UploadedFile uFile)
 61            throws MessagingException {
 62        DataSource source = new FileDataSource(uFile.getAbsolutePath());
 63        BodyPart messageBodyPart = new MimeBodyPart();
 64        messageBodyPart.setDataHandler(new DataHandler(source));
 65        messageBodyPart.setFileName(uFile.getName());
 66        multipart.addBodyPart(messageBodyPart);
 67    }
 68   
 69    public void reset() {
 70        to = null;
 71        subject = null;
 72        messageBodyText = null;
 73        files.clear();
 74    }
 75   
 76    /*
 77    public static void main(String args[]) {
 78        EmailSenderService ess = new EmailSenderService();
 79        ess.sendEmail();
 80    }
 81    */
 82
 83    public List<UploadedFile> getFiles() {
 84        return files;
 85    }
 86
 87    public void setFiles(List<UploadedFile> files) {
 88        this.files = files;
 89    }
 90
 91    public String getTo() {
 92        return to;
 93    }
 94
 95    public void setTo(String to) {
 96        this.to = to;
 97    }
 98
 99    public String getSubject() {
100        return subject;
101    }
102
103    public void setSubject(String subject) {
104        this.subject = subject;
105    }
106
107    public String getMessageBodyText() {
108        return messageBodyText;
109    }
110
111    public void setMessageBodyText(String messageBodyText) {
112        this.messageBodyText = messageBodyText;
113    }
114}


At the end I have substituted the firstNameField etc for the fields emailTo, subject and messageText and
on the other hand I use a similar code to get the differents files to attach to the email from the layer view.

Here is the code for the submit method in the ApplicantBackingBean.java file,

 1
 2    public String submit() {
 3
 4        if (logger.isDebugEnabled()) {
 5            logger.debug("emailTo=" + applicantModelBean.getEmailTo());
 6            logger.debug("subject=" + applicantModelBean.getSubject());
 7            logger.debug("messageText=" + applicantModelBean.getMessageText());
 8            
 9            List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();
10
11            for (UploadedFile uploadedFile : uploadedFiles) {
12                logger.debug("uploadedFile=[{0}]", uploadedFile.getName());
13            }
14        }
15
16        // Delete the uploaded files.
17        try {
18            
19            List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();
20            
21                        /*
22            emailSenderServiceBean.setTo(applicantModelBean.getEmailTo());
23            emailSenderServiceBean.setSubject(applicantModelBean.getSubject());
24            emailSenderServiceBean.setMessageBodyText(applicantModelBean.getMessageText());
25            emailSenderServiceBean.setFiles(uploadedFiles);
26            emailSenderServiceBean.sendEmail();
27            emailSenderServiceBean.reset();
28            */
29            
30                        for (UploadedFile uploadedFile : uploadedFiles) {
31                uploadedFile.delete();
32                logger.debug("Deleted file=[{0}]", uploadedFile.getName());
33            }
34
35            // Store the applicant's first name in JSF 2 Flash Scope so that it can be picked up
36            // for use inside of confirmation.xhtml
37            FacesContext facesContext = FacesContext.getCurrentInstance();
38            facesContext.getExternalContext().getFlash().put("subject", applicantModelBean.getSubject());
39
40            applicantModelBean.clearProperties();
41
42            return "success";
43
44        }
45        catch (Exception e) {
46            logger.error(e.getMessage(), e);
47            FacesMessageUtil.addGlobalUnexpectedErrorMessage(FacesContext.getCurrentInstance());
48
49            return "failure";
50        }
51    }


where emailSenderServiceBean is declared in the backing bean as a managed property

@ManagedProperty(value = "#{emailSenderServiceBean}")
private transient EmailSenderServiceBean emailSenderServiceBean;

But still does not work. I am thinking of the configurartion files in the WEB-INF folder. Just debugging these files I am getting
at less to deploy the portlet though it gives an error and doses not display the controlls.

Any help or suggestion should be appreciated.

Kind regards,
Jose
Jose Alvarez de Lara
RE: Attached files in an email client portlet, how to
April 15, 2013 5:42 AM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

Hi,

I have could get it works. Here is my applicant.xhtml file

 1
 2<?xml version="1.0"?>
 3<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:aui="http://liferay.com/faces/aui"
 4    xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core"
 5    xmlns:h="http://java.sun.com/jsf/html" xmlns:bridge="http://liferay.com/faces/bridge"
 6    xmlns:example-cc="http://java.sun.com/jsf/composite/example-cc" xmlns:ui="http://java.sun.com/jsf/facelets">
 7
 8    <aui:layout id="l1">
 9        <example-cc:clipboard label="#{i18n['email-client']}" />
10        <example-cc:sponsorButton />
11        <example-cc:divider />
12        <aui:column id="c1">
13            <h:form id="f1">
14                <h:messages globalOnly="true" layout="table" />
15                <aui:fieldset id="fs1">
16                    <aui:column id="c1a">
17                        <aui:field id="emailToField" label="#{i18n['email-to']}">
18                            <h:inputText id="emailTo" required="true" validatorMessage="#{i18n['invalid-email-address']}"
19                                value="#{applicantModelBean.emailTo}">
20                                <f:validateRegex pattern=".+[@].+[.].+" />
21                                <f:ajax render="emailToField" />
22                            </h:inputText>
23                            <h:message for="emailTo" />
24                        </aui:field>
25                        <aui:field id="subjectField" label="#{i18n['subject']}">
26                            <h:inputText id="subject" required="true" value="#{applicantModelBean.subject}">
27                                <f:ajax render="subjectField" />
28                            </h:inputText>
29                            <h:message for="subject" />
30                        </aui:field>
31                        <aui:field id="messageBodyTextField" label="#{i18n['message-body-text']}">
32                            <h:inputTextarea id="messageText" required="true" cols="75" rows="35" value="#{applicantModelBean.messageText}">
33                                <f:ajax render="messageBodyTextField" />
34                            </h:inputTextarea>
35                            <h:message for="messageText" />
36                        </aui:field>
37                    </aui:column>
38                </aui:fieldset>
39                <hr />
40                <h:commandButton action="#{applicantBackingBean.submit}" value="#{i18n['submit']}">
41                    <f:ajax execute="@form" render="@form" />
42                </h:commandButton>
43                <!-- Test 5.4.2 Encoding PortletMode changes in Faces navigation -->
44                <h:commandButton
45                    action="/views/portletEditMode.xhtml?javax.portlet.faces.PortletMode=edit&amp;javax.portlet.faces.WindowState=maximized"
46                    immediate="true" value="#{i18n['edit-preferences']}" />
47            </h:form>
48        </aui:column>
49        <aui:column id="c2">
50            <aui:column id="c2a" styleClass="uploaded-files">
51                <h:form id="f2">
52                    <h3>#{i18n['attachments']}</h3>
53                    <h:dataTable headerClass="portlet-section-header results-header"
54                        rowClasses="portlet-section-body results-row, portlet-section-alternate results-row alt"
55                        value="#{applicantModelBean.uploadedFiles}" var="uploadedFile">
56                        <h:column>
57                            <h:commandButton actionListener="#{applicantBackingBean.deleteUploadedFile}"
58                                image="#{resource['example:icon-delete.png']}"
59                                onclick="if (! confirm('#{i18n['are-you-sure-you-want-to-delete-this']}')) {return false;}"
60                                value="#{uploadedFile.id}">
61                                <f:ajax render="@form" />
62                            </h:commandButton>
63                        </h:column>
64                        <h:column>
65                            <f:facet name="header">
66                                <h:outputText value="#{i18n['file-name']}" />
67                            </f:facet>
68                            <h:outputText value="#{uploadedFile.name}" />
69                        </h:column>
70                        <h:column>
71                            <f:facet name="header">
72                                <h:outputText value="#{i18n['size']}" />
73                            </f:facet>
74                            <h:outputText value="#{uploadedFile.size}" />
75                        </h:column>
76                    </h:dataTable>
77                </h:form>
78                <hr />
79                <h:form id="f3" enctype="multipart/form-data">
80                    <h:panelGrid columns="1">
81                        <bridge:inputFile fileUploadListener="#{applicantBackingBean.handleFileUpload}" multiple="multiple" />
82                    </h:panelGrid>
83                    <h:commandButton value="#{i18n['submit']}" />
84                </h:form>
85            </aui:column>
86        </aui:column>
87    </aui:layout>
88
89</ui:composition>


and here are the backing beans,

ApplicantBackingBean.-
  1
  2@ManagedBean(name = "applicantBackingBean")
  3@ViewScoped
  4public class ApplicantBackingBean implements Serializable {
  5
  6    // serialVersionUID
  7    private static final long serialVersionUID = 2947548873495692163L;
  8
  9    // Logger
 10    private static final transient Logger logger = LoggerFactory.getLogger(ApplicantBackingBean.class);
 11
 12    // Injections
 13    @ManagedProperty(value = "#{applicantModelBean}")
 14    private transient ApplicantModelBean applicantModelBean;
 15    @ManagedProperty(value = "#{emailSenderServiceBean}")
 16    private transient EmailSenderServiceBean emailSenderServiceBean;
 17   
 18    public void deleteUploadedFile(ActionEvent actionEvent) {
 19        UICommand uiCommand = (UICommand)actionEvent.getComponent();
 20        String fileId = (String)uiCommand.getValue();
 21        try
 22        {
 23          List<UploadedFile> uploadedFiles = this.applicantModelBean.getUploadedFiles();
 24   
 25          UploadedFile uploadedFileToDelete = null;
 26   
 27          for (UploadedFile uploadedFile : uploadedFiles)
 28          {
 29            if (uploadedFile.getId().equals(fileId)) {
 30              uploadedFileToDelete = uploadedFile;
 31   
 32              break;
 33            }
 34          }
 35   
 36          if (uploadedFileToDelete != null) {
 37            uploadedFileToDelete.delete();
 38            uploadedFiles.remove(uploadedFileToDelete);
 39            logger.debug("Deleted file=[{0}]", new Object[] { uploadedFileToDelete.getName() });
 40          }
 41        }
 42        catch (Exception e) {
 43          logger.error(e);
 44        }
 45      }
 46   
 47    public void handleFileUpload(FileUploadEvent fileUploadEvent) throws Exception {
 48        List<UploadedFile> uploadedFiles = this.applicantModelBean.getUploadedFiles();
 49        UploadedFile uploadedFile = fileUploadEvent.getUploadedFile();
 50   
 51        if (uploadedFile != null)
 52        {
 53          if (uploadedFile.getStatus() == UploadedFile.Status.FILE_SAVED) {
 54            uploadedFiles.add(uploadedFile);
 55            logger.debug("Received fileName=[{0}] absolutePath=[{1}]", new Object[] { uploadedFile.getName(), uploadedFile.getAbsolutePath() });
 56          }
 57          else
 58          {
 59            logger.error("Uploaded file status=[" + uploadedFile.getStatus().toString() + "] " + uploadedFile.getMessage());
 60   
 61            FacesMessageUtil.addGlobalUnexpectedErrorMessage(FacesContext.getCurrentInstance());
 62          }
 63        }
 64      }
 65
 66    public String submit() {
 67
 68        if (logger.isDebugEnabled()) {
 69            logger.debug("emailTo=" + applicantModelBean.getEmailTo());
 70            logger.debug("subject=" + applicantModelBean.getSubject());
 71            logger.debug("messageText=" + applicantModelBean.getMessageText());
 72            
 73            List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();
 74
 75            for (UploadedFile uploadedFile : uploadedFiles) {
 76                logger.debug("uploadedFile=[{0}]", uploadedFile.getName());
 77            }
 78        }
 79
 80        // Delete the uploaded files.
 81        try {
 82            
 83            List<UploadedFile> uploadedFiles = applicantModelBean.getUploadedFiles();
 84            
 85            emailSenderServiceBean.setTo(applicantModelBean.getEmailTo());
 86            emailSenderServiceBean.setSubject(applicantModelBean.getSubject());
 87            emailSenderServiceBean.setMessageBodyText(applicantModelBean.getMessageText());
 88            emailSenderServiceBean.setFiles(uploadedFiles);
 89            emailSenderServiceBean.sendEmail();
 90            
 91            emailSenderServiceBean.reset();
 92            
 93            for (UploadedFile uploadedFile : uploadedFiles) {
 94                uploadedFile.delete();
 95                logger.debug("Deleted file=[{0}]", uploadedFile.getName());
 96            }
 97
 98            // Store the applicant's first name in JSF 2 Flash Scope so that it can be picked up
 99            // for use inside of confirmation.xhtml
100            FacesContext facesContext = FacesContext.getCurrentInstance();
101            facesContext.getExternalContext().getFlash().put("subject", applicantModelBean.getSubject());
102
103            applicantModelBean.clearProperties();
104
105            return "success";
106
107        }
108        catch (Exception e) {
109            logger.error(e.getMessage(), e);
110            FacesMessageUtil.addGlobalUnexpectedErrorMessage(FacesContext.getCurrentInstance());
111
112            return "failure";
113        }
114    }
115
116    public void setApplicantModelBean(ApplicantModelBean applicantModelBean) {
117
118        // Injected via @ManagedProperty annotation
119        this.applicantModelBean = applicantModelBean;
120    }
121   
122    public void setEmailSenderServiceBean(EmailSenderServiceBean emailSenderServiceBean) {
123
124        // Injected via @ManagedProperty annotation
125        this.emailSenderServiceBean = emailSenderServiceBean;
126    }
127
128}


ApplicantModelBean.-
 1
 2@ManagedBean(name = "applicantModelBean")
 3@ViewScoped
 4public class ApplicantModelBean implements Serializable {
 5
 6    // serialVersionUID
 7    private static final long serialVersionUID = 7459628254337818761L;
 8
 9    // Private Data Members
10    private List<UploadedFile> uploadedFiles;
11    private String emailTo;
12    private String subject;
13    private String messageText;
14
15    public ApplicantModelBean() {
16        clearProperties();
17    }
18
19    public void clearProperties() {
20        uploadedFiles = new ArrayList<UploadedFile>();
21        emailTo = null;
22        subject = null;
23        messageText = null;
24    }
25   
26    public String getEmailTo() {
27        return emailTo;
28    }
29
30    public void setEmailTo(String emailTo) {
31        this.emailTo = emailTo;
32    }
33
34    public String getSubject() {
35        return subject;
36    }
37
38    public void setSubject(String subject) {
39        this.subject = subject;
40    }
41
42    public String getMessageText() {
43        return messageText;
44    }
45
46    public void setMessageText(String messageText) {
47        this.messageText = messageText;
48    }
49
50    public List<UploadedFile> getUploadedFiles() {
51        return uploadedFiles;
52    }
53
54}


It is important to say that I have removed any entry to Apache MyFaces in the pom.xml file
and inthe web.xml file as well.

Regards
Jose
Neil Griffin
RE: Attached files in an email client portlet, how to
April 15, 2013 9:12 AM
Answer

Neil Griffin

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2056

Join Date: July 26, 2005

Recent Posts

Hi Jose,

Very glad to hear that you got it working. BTW, you might want to check out the MailEngine and/or MailServiceUtil classes for convenient APIs for sending emails from a Liferay-based portlet.

Neil
Juan Gonzalez
RE: Attached files in an email client portlet, how to
April 15, 2013 1:59 PM
Answer

Juan Gonzalez

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1872

Join Date: October 28, 2008

Recent Posts

Hi Jose,

Just a note.

Why ApplicantBackingBean has View Scope? I see all attributes are transient, so in this case this bean is a "Controller" bean.

Probably you can change this to be @RequestScoped
Kyle Joseph Stiemann
RE: Attached files in an email client portlet, how to
April 16, 2013 12:12 PM
Answer

Kyle Joseph Stiemann

LIFERAY STAFF

Rank: Regular Member

Posts: 123

Join Date: January 14, 2013

Recent Posts

Juan,
Thanks so much for pointing that out. It might be the case that Jose designed his application similar to our jsf2-portlet ApplicantBackingBean which is @ViewScoped. But the only reason that it is @ViewScoped is because of the commentsRendered property. I just talked it over with Neil, and we're going to change that pattern a little and introduce a @ViewScoped ApplicantViewBean for the commentsRendered property. That will allow us to change the scope of the ApplicantBackingBean to @RequestScoped.

We just created FACES-1543 in order to track this issue.

Thanks,
- Kyle
Juan Gonzalez
RE: Attached files in an email client portlet, how to
April 16, 2013 1:00 PM
Answer

Juan Gonzalez

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1872

Join Date: October 28, 2008

Recent Posts

Yep, those "rendered" properties should be the only way (IMHO) of having a Managed Bean in View Scope (because of processing those values in RESTORE_VIEW phase).

ViewScope beans are used too much (sometimes people doesn't realize what's the impact following that practice). That's why many production apps becomes unusable after concurrent users growth.
Jose Alvarez de Lara
RE: Attached files in an email client portlet, how to
May 24, 2013 11:26 AM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

Hi guys, thanks a lot for your replies.

Yes the reasson why the backing bean is @ViewScoped is beacause what Kyle says, I took it from your JSF2 Portlet example
released December 1, 2012,

JSF2 Portlet

Juan I am not an expert in JSF so any suggestion I should have it really glad emoticon

Thanks again,
Jose
Juan Gonzalez
RE: Attached files in an email client portlet, how to
May 25, 2013 1:47 PM
Answer

Juan Gonzalez

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1872

Join Date: October 28, 2008

Recent Posts

My only suggestion at the moment would be not using @ViewScoped at any time. It should be used few times as possible and with few attributes in those beans.
Jose Alvarez de Lara
RE: Attached files in an email client portlet, how to
May 28, 2013 8:03 AM
Answer

Jose Alvarez de Lara

Rank: Junior Member

Posts: 45

Join Date: December 10, 2012

Recent Posts

Yes I will review my code and put it as you say.

Thanks,
jose