Struts 2/ Foundation 5 - ModelDriven class and File upload

纵然是瞬间 提交于 2019-12-12 16:24:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!