问题
I am new to Java programming and I am trying to create a basic webpage with form etc for placing an order. I decided to use Struts 2 after attending a couple of sessions at work. I also used zurb Foundation 5 for responsive UI. I was able to create a HTML webpage and a form with text fields etc and on the submission of the form, emails are sent to the customer and site owner with the form data.
I am now trying to add the file upload functionality to the form. The issue I am facing is that the file upload is successful but the other form data is not being populated and is wiped out in the email.
Please find the code below.
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?
回答1:
Your problem is that you are defining a wrong Interceptor Stack for your Action.
The default one is defaultStack
, while the one you used after the FileUpload
Interceptor is the basicStack
.
As you can see in the official documentation, the basicStack
has no ModelDriven
support. Change your action configuration from :
<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 :
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">image/jpeg,image/png,image/gif</param>
<param name="fileUpload.maximumSize">4194304</param>
</interceptor-ref>
Also consider using Struts2 tags to generate the HTML (use simple
theme for the maximum control of the generated HTML, or XHTML
, the default one, for the maximum assistance in HTML generation).
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.
The HTML will be cleaner and you will code it faster.
来源:https://stackoverflow.com/questions/24884568/struts-2-foundation-5-modeldriven-class-and-file-upload