我是Java编程的新手,我正在尝试创建带有 表单等用于下订单的基本网页。在参加了 几次工作会议后,我决定使用Struts 2 。我还将zurb Foundation 5用于响应式UI。我 能够创建一个HTML网页和一个带有文本字段等 的表单,并且在提交表单时,会将包含 表单数据的电子邮件发送给客户和网站所有者。
我现在正在尝试将文件上传功能添加到表单中。我 面临的问题是文件上传成功,但是其他表单数据没有 被填充并且在电子邮件中被清除。
请在下面找到代码。
WebContent/WEB-INF/submitAssign.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title></title> <link rel="stylesheet" href="css/foundation.css" /> <link rel="stylesheet" href="code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css"> <script src="code.jquery.com/jquery-1.10.2.js"></script> <script src="code.jquery.com/ui/1.11.0/jquery-ui.js"></script> <link href="images/icon_small.jpg" rel="shortcut icon" type="jpeg"/> </head> <body> <div class="row"> <img class="smallscreen" src="images/bannersmall.jpg" alt="slide 1"/> <img src="images/banner.jpg" alt="slide 1"/> </div> <div class="row"> <div class="large-12 columnsrow"> <nav class="top-bar show-for-medium-up"> <section class="top-bar-section"> <ul class="left"> <li><a href="index.html" class="button">Home</a></li> <li><a href="submitAssign.html" class="button">Submit</a></li> <li><a href="faqsPage.html" class="button">FAQs</a></li> <li><a href="contactUs.html" class="button">Contact</a></li> </ul> </section> </nav> </div> </div> <div class="off-canvas-wrap" data-offcanvas> <div class="inner-wrap"> <nav class="tab-bar hide-for-medium-up"> <section class="left-small"> <a class="left-off-canvas-toggle menu-icon"><span></span></a> </section> <section class="middle tab-bar-section"> <h1 class="title">Menu</h1> </section> </nav> <aside class="left-off-canvas-menu"> <ul class="off-canvas-list"> <li><label>FileUploadExample</label></li> <li><a href="index.html" class="button">Home</a></li> <li><a href="submitAssign.html" class="button">Submit</a></li> <li><a href="faqsPage.html" class="button">FAQs</a></li> <li><a href="contactUs.html" class="button">Contact</a></li> </ul> </aside> <br><br> <div class="row"> <div class = "panel"> <div class = "large-12 columnsrow"> <form id="assign-form" action="submitAssign" method="post" enctype='multipart/form-data' data-abide> <div class="row"> <div class = "large-7 columns"> <div class="email-field"> <label>Email <small>required</small> <input name="email" type="email" placeholder="john.doe@email.com" required> </label> <small class="error">Please enter a valid email address</small> </div> </div> <div class = "large-5 columns"> <div class="phone-field"> <label>Phone Number <small>required</small> <input name="phoneNum" type="tel" pattern="[+]?[1-9]\d*" required placeholder="9999999999" /> </label> <small class="error">Please enter a valid phone number</small> </div> </div> </div> <div class="row"> <div class = "large-12 columns"> <div class="name-field"> <label>Name <small>required</small> <input name="custName" type="text" required pattern="[\sa-zA-Z]+"> </label> <small class="error">Only alphabets are allowed </small> </div> </div> </div> <div class="row"> <div class = "large-4 columns"> <div class="subject-field"> <label>Subject <input name="assignSubject" type="text" required pattern="[\sa-zA-Z]+"> </label> <small class="error">Only alphabets are allowed </small> </div> </div> <div class = "large-4 columns"> <div class="pages-field"> <label>No. of Pages <input name="noOfPages" type="tel" pattern="[1-9]\d*"> </label> <small class="error">Please enter a number value </small> </div> </div> <div class = "large-4 columns"> <div class="words-field"> <label>No. of Words <input name="noOfWords" type="tel" pattern="[1-9]\d*" > </label> <small class="error">Please enter a number value </small> </div> </div> </div> <div class="row"> <div class = "large-4 columns"> <label>Deadline <input name ="lastDate" type="date" required> </label> <small class="error">Please enter a valid date </small> </div> <div class = "large-8 columns"> </div> </div> <div class="row"> <div class = "large-12 columns"> <div class="desc-field"> <label>Description <textarea name="descAssign" placeholder="Please describe here..."></textarea> </label> </div> </div> </div> <div class="row"> <div class="large-12 columns"> <div class="file-upload"> <label>Select Attachment <input id="file" type="file" name="assignUpload" /> </label> </div> </div> </div> <button type="submit">Submit</button> </form> </div> </div> </div> </div> </div> <br><br><br> <a class="exit-off-canvas"></a> <script src="js/vendor/jquery.js"></script> <script src="js/foundation.min.js"></script> <script src="js/foundation/foundation.abide.js"></script> <script> $(document).foundation(); </script> <script> $('#assign-form') .on('invalid.fndtn.abide', function () { var invalid_fields = $(this).find('[data-invalid]'); console.log(invalid_fields); }) .on('valid.fndtn.abide', function () { $('#date'). console.log('valid!'); }); </script>
struts.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.multipart.maxSize" value="10485760" /> <package name="assignUpload" extends="struts-default" namespace="/"> <action name="submitAssign" class="com.assignupload.actions.SubmitAssignment"> <interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg,image/png,image/gif</param> <param name="maximumSize">4194304</param> </interceptor-ref> <interceptor-ref name="basicStack"></interceptor-ref> <result name="success">submitSuccess.html</result> <result name="error">submitError.html</result> </action> </package> </struts>
SubmitAssignment.java
package com.assignupload.actions; import java.io.File; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import com.assignupload.pojo.AssignmentInfo; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class SubmitAssignment extends ActionSupport implements ModelDriven, ServletRequestAware { private File[] assignUpload; private String[] assignUploadFileName; private String[] assignUploadContentType; AssignmentInfo assignInfo = new AssignmentInfo(); @Override public Object getModel() { return assignInfo; } @Override public String execute() throws Exception { System.out.println(assignInfo); ServletContext servletContext = ServletActionContext.getServletContext(); String dataDir = servletContext.getRealPath("/WEB-INF"); for (int i = 0; i < assignUpload.length; i++){ File savedFile = new File(dataDir, assignUploadFileName[i]); assignUpload[i].renameTo(savedFile); } try{ SendOrderEmail sendEmail = new SendOrderEmail(assignInfo); sendEmail.sendEmail();} catch (Exception e){ e.printStackTrace(); return ERROR; } return SUCCESS; } public File[] getAssignUpload() { return assignUpload; } public void setAssignUpload(File[] assignUpload) { this.assignUpload = assignUpload; } public String[] getAssignUploadFileName() { return assignUploadFileName; } public void setAssignUploadFileName(String[] assignUploadFileName) { this.assignUploadFileName = assignUploadFileName; } public String[] getAssignUploadContentType() { return assignUploadContentType; } public void setAssignUploadContentType(String[] assignUploadContentType) { this.assignUploadContentType = assignUploadContentType; } @Override public void setServletRequest(HttpServletRequest arg0) { // TODO Auto-generated method stub } }
AssignmentInfo.Java
package com.assignupload.pojo; import java.io.File; public class AssignmentInfo { private String email; private Long phoneNum; private String custName; private String assignSubject; private int noOfPages; private int noOfWords; private String lastDate; private String descAssign; public AssignmentInfo() { // TODO Auto-generated constructor stub } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Long getPhoneNum() { return phoneNum; } public void setPhoneNum(Long phoneNum) { this.phoneNum = phoneNum; } public String getCustName() { return custName; } public void setCustName(String custName) { this.custName = custName; } public String getAssignSubject() { return assignSubject; } public void setAssignSubject(String assignSubject) { this.assignSubject = assignSubject; } public int getNoOfPages() { return noOfPages; } public void setNoOfPages(int noOfPages) { this.noOfPages = noOfPages; } public int getNoOfWords() { return noOfWords; } public void setNoOfWords(int noOfWords) { this.noOfWords = noOfWords; } public String getLastDate() { return lastDate; } public void setLastDate(String lastDate) { this.lastDate = lastDate; } public String getDescAssign() { return descAssign; } public void setDescAssign(String descAssign) { this.descAssign = descAssign; } @Override public String toString() { return "AssignmentInfo [email=" + email + ", phoneNum=" + phoneNum + ", custName=" + custName + ", assignSubject=" + assignSubject + ", noOfPages=" + noOfPages + ", noOfWords=" + noOfWords + ", lastDate=" + lastDate + ", descAssign=" + descAssign + "]"; } }
Besides the above code I have a SendOrderEmail.java file which is successfully sending the emails.
Here is the error log in eclipse.
INFO 2014-07-22 14:27:04,351 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.Dispatcher - Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir DEBUG2014-07-22 14:27:04,351 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.Dispatcher - saveDir=C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\AssignmentUpload DEBUG2014-07-22 14:27:04,428 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item email DEBUG2014-07-22 14:27:04,428 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,429 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item phoneNum DEBUG2014-07-22 14:27:04,429 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,430 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item custName DEBUG2014-07-22 14:27:04,430 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,431 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item assignSubject DEBUG2014-07-22 14:27:04,431 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,432 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item noOfPages DEBUG2014-07-22 14:27:04,432 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,432 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item noOfWords DEBUG2014-07-22 14:27:04,432 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,433 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item lastDate DEBUG2014-07-22 14:27:04,433 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,434 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item descAssign DEBUG2014-07-22 14:27:04,434 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a normal form field DEBUG2014-07-22 14:27:04,434 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Found item assignUpload DEBUG2014-07-22 14:27:04,435 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Item is a file upload DEBUG2014-07-22 14:27:04,448 [http-bio-8080-exec-7] com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler - Entering nullPropertyValue [target=[com.opensymphony.xwork2.DefaultTextProvider@1ac8b63], property=struts] DEBUG2014-07-22 14:27:04,457 [http-bio-8080-exec-7] com.opensymphony.xwork2.DefaultActionProxy - Creating an DefaultActionProxy for namespace [/] and action name [submitAssign] DEBUG2014-07-22 14:27:04,482 [http-bio-8080-exec-7] com.opensymphony.xwork2.interceptor.ParametersInterceptor - Setting params NONE DEBUG2014-07-22 14:27:04,482 [http-bio-8080-exec-7] com.opensymphony.xwork2.interceptor.ParametersInterceptor - Setting params assignUploadFileName => [ 1235962_10151872148662472_2018380961_n.jpg ] noOfWords => [ 1000 ] phoneNum => [ 919766759029 ] noOfPages => [ 4 ] email => [ xxxxxx@gmail.com ] descAssign => [ Image test 6 ] assignSubject => [ Astronomy ] lastDate => [ 2014-07-31 ] assignUpload => [ C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\AssignmentUpload\upload_1dec45bb_28eb_4942_9d60_566bc01b4d5d_00000008.tmp ] custName => [ XXXXX ] assignUploadContentType => [ image/jpeg ] DEBUG2014-07-22 14:27:04,486 [http-bio-8080-exec-7] com.opensymphony.xwork2.DefaultActionInvocation - Executing action method = null AssignmentInfo [email=null, phoneNum=null, custName=null, assignSubject=null, noOfPages=0, noOfWords=0, lastDate=null, descAssign=null] java.lang.NullPointerException at javax.mail.internet.InternetAddress.parse(InternetAddress.java:678) at javax.mail.internet.InternetAddress.parse(InternetAddress.java:638) at javax.mail.internet.InternetAddress.parse(InternetAddress.java:615) at com.assignupload.actions.SendOrderEmail.custEmail(SendOrderEmail.java:55) at com.assignupload.actions.SendOrderEmail.sendEmail(SendOrderEmail.java:41) at com.assignupload.actions.SubmitAssignment.execute(SubmitAssignment.java:44) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450) at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:252) at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:254) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:254) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:325) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562) at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Email to customer was not sent! DEBUG2014-07-22 14:27:18,318 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.ServletDispatcherResult - Forwarding to location submitSuccess.html DEBUG2014-07-22 14:27:18,336 [http-bio-8080-exec-7] com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler - Entering nullPropertyValue [target=[com.assignupload.actions.SubmitAssignment@19d85cd, com.opensymphony.xwork2.DefaultTextProvider@1ac8b63], property=struts] DEBUG2014-07-22 14:27:18,356 [http-bio-8080-exec-7] com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler - Entering nullPropertyValue [target=[com.assignupload.actions.SubmitAssignment@19d85cd, com.opensymphony.xwork2.DefaultTextProvider@1ac8b63], property=struts] DEBUG2014-07-22 14:27:18,367 [http-bio-8080-exec-7] org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest - Removing file assignUpload name=1235962_10151872148662472_2018380961_n.jpg, StoreLocation=C:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\AssignmentUpload\upload_1dec45bb_28eb_4942_9d60_566bc01b4d5d_00000008.tmp, size=96207 bytes, isFormField=false, FieldName=assignUpload
Could you please guide me as to why the form data is being wiped out?
您的问题是您为操作定义了错误的拦截器堆栈 。
默认的是defaultStack,而 FileUpload拦截器之后使用的是basicStack。
正如你所看到的在官方 文件,(http://struts.apache.org/release/2.3.x/docs/interceptors.html), the basicStack has no ModelDriven support. Change your action configuration from :
basicStack
ModelDriven
<interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg,image/png,image/gif</param> <param name="maximumSize">4194304</param> </interceptor-ref> <interceptor-ref name="basicStack"></interceptor-ref>
to :
<interceptor-ref name="fileUpload"> <param name="allowedTypes">image/jpeg,image/png,image/gif</param> <param name="maximumSize">4194304</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref>
or even better (to avoid using the FileUpload Interceptor twice) to :
FileUpload
<interceptor-ref name="defaultStack"> <param name="fileUpload.allowedTypes">image/jpeg,image/png,image/gif</param> <param name="fileUpload.maximumSize">4194304</param> </interceptor-ref>
还可以考虑使用Struts2标签生成HTML(使用simple主题 最大程度地控制生成的HTML,或者XHTML使用默认主题,以 获得最大的HTML生成帮助)。
In many of the tags (the ones with Dynamic Attributes Allowed: true in the documentation), like <s:textfield/>, <s:textarea/>, <s:file/> and so on, you can define your own attributes, like the HTML5 pattern , for example.
<s:textfield/>
<s:textarea/>
<s:file/>
pattern
HTML将更干净,您可以更快地编写代码。