精华内容
下载资源
问答
  • 文章目录Struts2框架学习笔记一:Struts2框架搭建、配置详解Struts2框架搭建Struts2拦截器的重要性struts2常量配置struts2动态调用struts2的默认值配置Action类的操作 Struts2框架学习笔记一:Struts2框架搭建、配置...

    1. Struts2框架学习笔记一:Struts2框架搭建、配置详解

    1.1. Struts2框架搭建

    1. 创建一个Dynamic web project项目
    2. 在lib文件下导入相应的包,解压Struts压缩包
    • 在G:\struts-2.3.24\apps找struts-blank.war,这里面包含Struts必须jar包。
    1. 书写Action测试类
    public class HelloAction {
        public String hello() {
            System.out.println("hello world");
            return "success";
        }
    }
    
    1. 书写Struts.xml配置文件
    • 添加struts2约束信息
    <!DOCTYPE struts PUBLIC
    	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    	"http://struts.apache.org/dtds/struts-2.3.dtd">
    
    • struts配置信息
    <struts>
    	<package name="hello" namespace="/hello" extends="struts-default">
    		<action name="HelloAction" class="com.itheima.web.HelloAction" method="hello">
    			<result name="success">/hello.jsp</result>
    		</action>
    	</package>
    </struts>
    
    • 首先配置包名信息。 ,namespace内容为访问的action名,这个要填正确,和前端的访问路径要一致。

    name: 随意填,这里是包名,可以被继承。

    namespace: 内容为访问的action名。这个要和前端的访问路径要一致,否则会找不到。

    extends: 表示继承那个包,如果继承了谋个包,那么该包里的所有配置都会被继承。这里继承了struts-default包

    注意: 对于namespace问题,这样想,首先通过url访问,会被拦截器拦截,拦截器根据url去匹配namespace,比如:httt://localhost: 8080/Struts2/test/test2/testMap.action 这个拦截器会到struts.xml去找namespace为/test/test2的package ,如果找不到,就去找namespace为/test的package,如果还是找不到这样的package,就会去找namespace值为/的namespace,这个是默认的,就会去找里面是否有testMap.action,如果没找到,就报没有/test/test2的错。参考文章

    一定要注意拦截器寻找的是namespace,而不是某个action.

    • 其次配置action内容

    name: 为Action类名。

    class: 为Action类全限名。

    method: 为本次访问要访问的这个类的那个方法。

    • result配置信息

    name: 为return返回后的值,如果为该值信息,就转向该result包裹内的结果。

    type: 指定调用哪一个result类来处理结果,默认使用转发.
    标签体: 填写页面的相对路径

    • Struts2访问流程

    点击前端–>生成url访问路径–>过滤器过滤url–>过滤器拦截Action–>从struts.xml中查找该Action–>进而找到该类–>进而找到该类的方法–>处理方法,返回结果–>转向result包裹的内容。

    1. 配置web.xml
    <filter>
        <filter-name>struts2</filter-name>
      <filterclass>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    1.2. Struts2拦截器的重要性

    1. Struts拦截器帮助我们封装了很多功能。
    2. 拦截器优秀的设计,可插拔设计,即可以添加拦截器,还可以改装
    3. aop思想,面向切面编程:即纵向重复代码,横向抽取。

    aop思想

    • Struts2中的应用

    aop思想在struts2中的应用

    1.3. struts2常量配置

    1. Struts2的常量配置就是重写default.properties文件里的一些配置信息
    2. Struts2默认加载顺序是,properties–>Struts.xml–>web.xml,如果重复,后加载会覆盖先加载内容。
    3. Struts2常量配置可以在三个地方配置,即:

    一、 在src下添加struts.properties文件二、 在struts.xml中添加常量配置,一般选择在此处配置常量。

    三、 在web.xml中添加常量配置

    1. 配置内容
    • i18n国际化配置,根据浏览器编码解决post乱码问题,get方法提交无效
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    
    • 指定访问action时的后缀名,value=action,表示访问action时后缀为.action或者没有后缀都可以,两个逗号表示无后缀也可以。
    <constant name="struts.action.extension" value="action"></constant>
    
    • 指定struts2是否以开发模式运行,一是热加载主配置.(不需要重启即可生效),二是提供更多错误信息输出,方便开发时的调试
    <constant name="struts.devMode" value="true"></constant>
    

    1.4. struts2动态调用

    1. 利用通配符*实现动态调用
    <action name="CustomerAction_*" class="cn.it.web.action.CustomerAction" method="{1}" >
        <result name="list" >/jsp/customer/list.jsp</result>
    </action>
    
    • name 属性里面有一个通配符,会记录前提传来的内容,并将该值传递给method的属性{1}中。实现动态调用该Action中的方法。

    1.5. struts2的默认值配置

    1. method属性默认方法是execute()方法,如果不写,就执行该方法。
    2. result的name属性是success
    3. result的type属性是dispatcher转发
    4. class的默认属性是com.opensymphony.xwork2.ActionSupport,默认找name属性中的Action

    1.6. Action类的操作

    1. Action类需要继承ActionSupport
    public class CustomerAction extends ActionSupport {}
    
    • 帮助我们实现了validateable,validationAware,TextProvider,LocalProvider.自己需要这些时不需要再实现了。
    展开全文
  • Struts2 框架

    2008-08-29 10:58:00
    一 . Struts2 简介 Struts2的目标很简单——使Web开发变得更加容易。为了达成这一目标,Struts2中提供...2. Struts2中的Action都是POJO,这一方面增强了Action本身的可测试性,另一方面也减小了框架内部的耦合度,而

    .  Struts2  简介 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    Struts2的目标很简单——使Web开发变得更加容易。为了达成这一目标,Struts2中提供了很多新特性,比如:

    1. 智能的默认设置、annotation的使用以及惯例重于配置原则的应用,而这一切都大大减少了XML配置

    2. Struts2中的Action都是POJO,这一方面增强了Action本身的可测试性,另一方面也减小了框架内部的耦合度,而HTML表单中的输入项都被转换成了恰当的类型以供action使用。

    3. 开发人员还可以通过拦截器(可以自定义拦截器或者使用Struts2提供的拦截器)来对请求进行预处理和后处理,这样一来,处理请求就变得更加模块化,从而进一步减小耦合度。

    4. 模块化是一个通用的主题——可以通过插件机制来对框架进行扩展;

    5. 开发人员可以使用自定义的实现来替换掉框架的关键类,从而获得框架本身所不具备的功能;

    6. 可以用标签来渲染多种主题(包括自定义的主题);

    7. Action执行完毕以后,可以有多种结果类型——包括渲染JSP页面,VelocityFreemarker模板,但并不仅限于这些。

    8. 最后,依赖注入也成了Struts2王国中的一等公民,这项功能是通过Spring框架的插件和Plexus共同提供的,与PicoContainer的结合工作还正在进行中

     

     .  Struts2 框架结构

    1.      模型 Action

    单个结果   多个结果   结果类型   请求和表单的数据注入  IOC

    2.      控制 Servlet过滤器(拦截器)

    Web.xml / struts.properties    struts.xml    FilterDispacher过滤器   拦截器的配置  以及实现

    3.      视图 OGNL  

    值栈与OGNL  实现结果类型  配置    视图技术:velocity   freemarker

     .  Struts2Struts1的对比 

    Action 
    • Struts1
    要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 
    • Struts 2 Action
    类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2Action对象。 

    线程模式: 
    • Struts1 Action
    是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。 
    • Struts2 Action
    对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题) 

    Servlet 依赖
    • Struts1 Action 
    依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest  HttpServletResponse 被传递给execute方法。 
    • Struts 2 Action
    不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的requestresponse。但是,其他的元素减少或者消除了直接访问HttpServetRequest  HttpServletResponse的必要性。 

    可测性
    • 
    测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。 
    • Struts 2 Action
    可以通过初始化、设置属性、调用方法来测试,依赖注入支持也使测试更容易。 

    捕获输入
    • Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的类捕获输入。动态BeanDynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。 
    • Struts 2
    直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己()属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglibPOJO输入对象的引用。 

    表达式语言: 
    • Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。 
    • Struts2
    可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--
    "Object Graph Notation Language" (OGNL). 
    绑定值到页面(view
    • Struts 1使用标准JSP机制把对象绑定到页面中来访问。 
    • Struts 2 
    使用 "ValueStack"技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
     
     
     
    类型转换: 
    • Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。 
    • Struts2 
    使用OGNL进行类型转换。提供基本和常用对象的转换器。 

    校验: 
    • Struts 1支持在ActionFormvalidate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。 
    • Struts2
    支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性 

    Action执行的控制: 
    • Struts1
    支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。 
    • Struts2
    支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。 

     

     

    展开全文
  • Struts2框架原理

    千次阅读 2018-07-25 12:40:51
    Struts2官网 ... Struts2是一个开源的轻量级的,应用于web层(View)的框架。 Struts2框架的MVC分别对应: ...Struts2框架的控制器将“获取请求”和“分发转向”代码抽取出来写在配置文件中,这样一样,控制器(a...

    Struts2官网

    https://struts.apache.org/

    Struts2是一个开源的轻量级的,应用于web层(View)的框架。

     

    Struts2框架的MVC分别对应:

    M:JavaBean + ModelDriven

    V:JSP + OGNL

    C:Action

    Struts2框架的控制器将“获取请求”和“分发转向”代码抽取出来写在配置文件中,这样一样,控制器(action类)就能专注于业务逻辑的处理了。

     

    Struts2框架内部运行原理图

     

    Struts2五个核心部件

    1. Actions(动作)
    2. Interceptors(拦截器)
    3. Value Stack / OGNL(值栈 / OGNL)
    4. Results / Result types(返回结果)
    5. View technologies(视图)

     

    Action获取web对象

    使用ActionContext类(解耦方式——即struts2测试时不需要启动服务器,提高开发效率)

    Web应用中通常需要访问的Servlet API就是HttpServletRequest、HttpSession和ServletContext,这三个接口分别代表JSP内置对象中的request、session和application。

     

    Struts2提供了一个ActionContext类(com.opensymphony.xwork.ActionContext),它是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象。可以通过下面方法访问Servlet API:

    Object get(key)

    类似于HttpServletRequest的getAttribute(String)

    Map getApplication()

    返回一个Map对象

    static ActionContext getContext()

    返回静态的ActionContext实例,相当于HttpServletRequest对象

    HttpParameters  getParameters()

    获取所有的请求参数

    Map getSession()

    返回一个Map对象

    void setApplication(Map)

    向application传入一个Map对象

    void setSession(Map)

    向session传入一个Map对象

    void put(key, value)

    添加对象

     

    如何获得地址栏参数、表单参数:(struts版本不一样使用也不一样)

    ActionContext context = ActionContext.getContext();

     

    // 得到HttpServletRequest对象的attribute(解耦)

    Map<String, Parameter> paramsMap = context.getParameters();

    String type = paramsMap.get("type").toString();

     

    // 得到request对象

    HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);

    String type2 = request.getParameter("type");

    案例1:使用ActionContext操作作用域

    ActionContext ac = ActionContext.getContext();

    Integer count = (Integer) ac.getApplication().get(“count”);

    // 通过ActionContext设置application范围的属性

    ac.getApplication().put(“count”, 100);

    // 通过ActionContext设置session范围的属性

    ac.getSession().put(“max”, 1000);

    // 通过ActionContext设置request范围的属性

    ac.put(“min”, 10);

     

    前端页面:

    统计总人数:${applicationScope.count}

    最大人数:${sessionScope.max}

    最小人数:${requestScope.min}

     

    案例2:使用ActionContext获得JSP表单中的数据

    (1)创建表单,提交表单到action里面

    <form action=”/register” method=”post”>

    用户名:<input type=”text” name=”uname” />

    手机号:<input type=”text” name=”moblie” />

    性别:<input type=”radio” name=”sex” value=”1” / >男 <input type=”radio” name=”sex” value=”0” />女

        <input type=”submit” value=”提交” />

    </form>

     

    (2)在action使用ActionContext获取表单数据:

    ActionContext ac = ActionContext.getContext();

    // map的key就是表单项的各name

    Map<String, Object> map = ac.getParameters();

     

    //查看Map中的数据

    Set<String> keys = map.keyset();

    for(String key : keys){

        Object[] obj = (Object[])map.get(key);

    System.out.println(Arrays.toString(obj));

    }

    使用ServletActionContext类(耦合方式)

    HttpServletRequest request = ServletActionContext.getRequest();

    request.setAttribute("request", "1");

     

    HttpSession session = request.getSession();

    session.setAttribute("session", "2");

     

    ServletContext application = request.getSession().getServletContext();

    application.setAttribute("application", "3");

    不建议直接访问servlet的API,不利于项目移植。

    使用ServletXxxAware接口注入(耦合方式)

    使用ServletContextAware、ServletRequestAware、ServletResponseAware三个接口可直接获得Servlet API。

    Step1:类实现ServletResponseAware接口(或其它两个接口)。

    Step2:重写相应的方法:

    // 自定义类实现:ServletXXXAware接口,实现方法

    public class Test implements ServletRequestAware,ServletSessionAware……{

    private HttpServletRequest request;

     

        @Override

        public void setServletRequest(HttpServletRequest request){

            this.request = request;

        }

     

        public String execute() throws Exception{

            return NONE;

        }

    }

     

    Action表单数据封装(属性驱动、模型驱动)

    案例:表单数据提交

    对应数据在前台与后台中的交互,Struts2框架替我们做了很大部分的数据封装工作。既可以封装单个对象,也可以封装集合。

     

    实现Action有两大方式:属性驱动模型驱动

    (1)属性驱动

    使用属性作为贯穿MVC流程的信息携带者,依附于Action实例,Action实例封装请求参数和处理结果。

    属性驱动有三种:普通POJO实现Action接口继承ActionSupport推荐

    普通POJO类

    实现一个登录Action:

    public class LoginAction {

        //私有属性

        private String username;

        private String password;

    //struts2的拦截器机制,getter/setter方法负责解析用户请求参数,并且将请求参数值赋给action对应的属性(也就是说将form表单的数据赋值给Action类中的属性,属性名与表单项控件名一致)

    //此处省略set和get方法

     

        public String execute() throws Exception {

            if("test".equals(getUsername()) && "123".equals(getPassword())){

                return "success";

            }else{

                return "error";

            }

        }

    }

    实现Action接口

    为了让用户开发的Action类更加规范,Struts2提供Action接口,定义了Action处理类应该实现的规范。

     

    实现步骤:

    1. Action类实现Action接口,重写execute()方法,返回时使用Action接口中的常量;
    2. 在Action中声明成员变量,成员变量名与表单项name属性一致;
    3. 封装。

     

    案例:

    //1. 实现Action接口

    public class LoginAction implements Action {

        //2. 私有属性

        private String username;

        private String password;

    //3. 此处省略set和get方法

     

    //返回使用Action接口中的常量

        public String execute() throws Exception {

            if("test".equals(getUsername()) && "123".equals(getPassword())){

                return SUCCESS;

            }else{

                return ERROR;

            }

        }

    }

     

    Action接口代码:

    public interface Action{

        // 定义Action接口里包含的一些结果字符串

    public static final String ERROR=error;

    public static final String INPUT=input;

    public static final String LOGIN=login;

    public static final String NONE=none;

    public static final String SUCCESS=success;

    // 定义处理用户请求的execute方法

    public String execute() throws Exception;

    }

     

    继承ActionSupport类(推荐)

    ActionSupport类是Action接口的实现类。该类提供了许多默认的方法,这些默认方法包括获得国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。

    如果配置Action没的指定的Action类,系统自动使用ActionSupport类作为Action处理类。

     

    实现步骤:

    1. 继承ActionSupport,重写execute()方法。不继承也可以,直接写execute()方法;
    2. 在Action中声明成员变量,成员变量名与表单项name属性一致;
    3. 封装。

     

    案例:

    //1. 继承ActionSupport类

    public class LoginAction extends ActionSupport {

        //2. 声明成员变量(与表单项name一致,这里最好是私有化一个实体类对象,参见后面的)

        private String username;

        private String password;

    //3. 封装,省略getter/setter方法

    //struts2的拦截器机制,getter/setter方法负责解析用户请求参数,并且将请求参数值赋给action对应的属性

     

        public String execute() throws Exception {

            if("test".equals(getUsername()) && "123".equals(getPassword())){

                return SUCCESS;

            }else{

                return ERROR;

            }

        }

    }

    (2)模型驱动

    就是使用单独的JavaBean实例来贯穿整个MVC流程,JavaBean实例封装请求参数和处理结果。

    模型驱动有一种:ModelDriven

    模型驱动封装:ModelDriven(推荐)

    模型驱动:就是使用单独的JavaBean实例来贯穿整个MVC流程,JavaBean实例封装请求参数和处理结果。

     

    实现步骤:

    (1)Action类实现ModelDriven接口;

    (2)实现接口的getModel()方法,并把创建对象返回;

    (3)在Action中创建实体类对象;

    (4)execute()一样法中使用实体类对象名即可。

     

    案例:

    //1. 实现ModelDriven接口

    public class LoginAction3 implements ModelDriven<User> {

        //定义用于封装请求参数和处理结果的Model

    private User user = new User();

        //2. 实现接口的getModel()方法,并把创建对象返回

        @Override

        public User getModel() {

            return user;

        }

        //4. 在execute()中使用对象

        public String execute() throws Exception {

            if("test".equals(user.getUsername()) && "123".equals(user.getPassword())){

                return SUCCESS;

            }else{

                return ERROR;

            }

        }

    }

     

    User类:属性名要与表单控件名字相同,否则报错。

    //3. 创建实体类并封装

    public class User implements Serializable{

        private static final long serialVersionUID = 1L;

        // 私有的请求参数

        private String username;

        private String password;

    // 省略set和get方法

     

        public User() {

        }

        public User(String username, String password) {

            super();

            this.username = username;

            this.password = password;

        }

        @Override

        public String toString() {

            return "User [username=" + username + ", password=" + password + "]";

        }

    }

     

    (在这里简单说一下本人在使用struts2开发时,在对Action类使用时继承的是pojo(entity)类,在实体类中可以实现接口ModelDriven,重写getModel()方法返回this 或者 不实现接口自己写 一个方法返回this。因为之前有提到 如果配置Action没的指定的Action类,系统自动使用ActionSupport类作为Action处理类。所以当Action类继承pojo(entity)类时不管是属性驱动获值还是模型驱动获值都可以。在Action中就不必封装属性或对象)

     

     

    展开全文
  • Struts2框架实现文件上传

    万次阅读 2018-04-24 10:59:54
    Struts2框架实现文件上传开发环境系统:Windows10 版本1709JDK:1.8.0_161 32位IDE: Spring Tool Suite 3.7.3 32位Struts2版本:2.3.24服务器版本:apache-tomcat-7.0.52 单文件的上传环境搭建导入必要的jar包 必须有...

    Struts2框架实现文件上传

    • 开发环境
    • 系统:Windows10 版本1709
    • JDK:1.8.0_161 32位
    • IDE: Spring Tool Suite 3.7.3 32位
    • Struts2版本:2.3.24
    • 服务器版本:apache-tomcat-7.0.52

    单文件的上传

    环境搭建

    • 导入必要的jar包

    必须有commons-fileupload-1.3.1.jar包. 在开发Struts2框架必备的13个jar包中,包含了此jar包.

    • 在web.xml中配置核心的过滤器

      <filter>
          <filter-name>struts</filter-name>
          <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      </filter>
      
      <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>        
      </filter-mapping>  
      

    • 在src目录下创建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">
      

    文件上传的浏览器的三要素

    • 表单的提交方式必须为post

    • 表单中必须有一个<\input type="file">

    • 表单设置enctype="multipart/form-data"

      创建一个upload.jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="${pageContext.request.contextPath}/up" method="post" enctype="multipart/form-data">
            <input type="file" name="upload">
            <input type="summit" value="上传">
        </form>
    </body>
    </html>
    

    文件上传的服务器端

    创建一个UploadAction的java类

    public class UploadAction {
    
        private File upload;//定义一个File ,变量名要与jsp中的input标签的name一致
        private String uploadContentType;//上传文件的mimeType类型
        private String uploadFileName;//上传文件的名称
    
        public File getUpload() {
            return upload;
        }
        public void setUpload(File upload) {
            this.upload = upload;
        }
        public String getUploadContentType() {
            return uploadContentType;
        }
        public void setUploadContentType(String uploadContentType) {
            this.uploadContentType = uploadContentType;
        }
        public String getUploadFileName() {
            return uploadFileName;
        }
        public void setUploadFileName(String uploadFileName) {
            this.uploadFileName = uploadFileName;
        }
    
        public void uploadFile(){
            try {
                //在WebContent下新建一个upload的文件夹,获取其在服务器的绝对磁盘路径
                String path = ServletActionContext.getServletContext().getRealPath("/upload");
    
                //创建一个服务器端的文件
                File dest = new File(path,uploadFileName);
    
                //完成文件上传的操作
                FileUtils.copyFile(upload, dest);
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在struts.xml中进行如下的配置

    <struts>
        <!--配置开发者模式,可以显示更加详细的错误信息 -->
        <constant name="struts.devMode" value="true"></constant>
        <constant name="struts.multipart.maxSize" value="20971520"></constant>
        <package name="upload_demo" extends="struts-default" namespace="/" >
            <!-- <interceptors>
                <interceptor-stack name="myStack">
                    <interceptor-ref name="fileUpload">
                        设置上传文件允许的后缀名,多个使用逗号隔开 
                        <param name="allowedExtensions">avi,txt</param>
                    </interceptor-ref>
                    配置了其他的拦截器,就需要手动导入默认的拦截器
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>
            </interceptors> -->
            <action class="com.thc.action.UploadAction" method="uploadFile" name="up">
                <result name="input">/error.jsp</result>
                <interceptor-ref name="fileUpload">
                    <param name="maximumSize"></param><!-- 设置每一个action允许的上传文件的大小 -->
                    <param name="allowedTypes"></param><!--设置上传允许的文件的mimeType类型,多个使用逗号分开-->
                    <param name="allowedExtensions">bmp,txt</param><!-- 设置上传文件允许的后缀名,多个使用逗号分开 -->
                </interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </action>
        </package>
    </struts>
    

    使用Struts2框架实现文件上传.在页面的<input type="file" name="upload">name属性的名字,必须与文件上传的Java类中定义的File类型变量的名字一样.

    文件类型和文件名称的变量名也必须为name之后的拼接

    注意上传的文件是个临时文件,服务器重启后,文件就不存在了. 要想永久的保存,需要指定一个本地硬盘的目录.

    文件上传出现的问题以及解决方案

    文件的大小问题

    如果上传一个较大的文件,控制台会报空指针异常.这个空指针的异常信息不够详细.

    把当前的文件上传的java类继承ActionSupport类底层会去调用保存错误信息的方法. 并且在struts.xml文件中,开启开发者模式.

    <constant name="struts.devMode" value="true"></constant>

    再次上传一个较大的文件,会发现这次在报的错误不再是空指针异常. 控制台报错信息如下:

    [http-bio-8080-exec-10] ERROR org.apache.struts2.dispatcher.Dispatcher - Could not find action or result
    /strust2_fileupload/up
    com.opensymphony.xwork2.config.ConfigurationException: No result defined for action com.thc.action.UploadAction and result input
    

    这是说当前的文件上传的java类没有配置result 的input视图.

    这是因为Struts底层的拦截器如果出现问题,那么就会把错误信息存储到action中, workflow的拦截器负责控制跳转到指定的input视图.

    在struts.xml中的\ 标签中配置\名为input的视图 ,标签体为error.jsp

    <struts>
        <!--配置开发者模式,可以显示更加详细的错误信息 -->
        <constant name="struts.devMode" value="true"></constant>
        <package name="upload_demo" extends="struts-default" namespace="/" >
            <action name="up" class="com.thc.action.UploadAction" method="uploadFile">
            <result name="input">/error.jsp</result>
            </action>
        </package>
    </struts>
    

    在WebContent下新建一个error.jsp页面

    在jsp页面的顶部导入struts2框架的标签

    <%@taglib prefix="s" uri="/struts-tags" %>

    在页面中写上struts的标签<s:actionerror/><s:fielderror/> 用来显示提示错误信息

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@taglib prefix="s" uri="/struts-tags" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>错误信息显示页面</title>
    </head>
    <body>
        <h3>文件上传错误信息显示页面</h3>
        <s:actionerror/>
        <s:fielderror/>
    </body>
    </html>
    

    以上的操作做完了之后, 再次上传一个较大的文件.会在浏览器上看到如下的错误提示信息

    Request exceeded allowed size limit! Max size allowed is: 2,097,152 but request was: 1,346,882,290!

    提示是说,请求超出了最大的允许界限

    原因是在struts2框架default.properties配置文件中,定义了默认的文件上传大小为2097152字节(byte)为2M.

    在struts.xml的配置文件中,修改这个常量的大小.

    <constant name="struts.multipart.maxSize" value="20971520"></constant>

    修改为20M. 再次上传一个小于20M的文件后,就不会报错了. 这个文件大小的范围,依据实际的需求而设定.

    以上的改变常量方法是对所有的action生效,要想仅仅使一个action生效,设置上传文件的大小,需要在<action>标签中设置

    查看FileUploadInterceptor这个拦截器的源码

    发现有如下的属性:

        protected Long maximumSize;
        protected Set<String> allowedTypesSet = Collections.emptySet();
        protected Set<String> allowedExtensionsSet = Collections.emptySet();
    

    分别代表的是设置文件的最大大小,设置运行的文件类型,设置文件运行的后缀名.

    有如下的set方法,设置参数.

     /**
         * Sets the allowed extensions
         *
         * @param allowedExtensions A comma-delimited list of extensions
         */
        public void setAllowedExtensions(String allowedExtensions) {
            allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions);
        }
    
        /**
         * Sets the allowed mimetypes
         *
         * @param allowedTypes A comma-delimited list of types
         */
        public void setAllowedTypes(String allowedTypes) {
            allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes);
        }
    
        /**
         * Sets the maximum size of an uploaded file
         *
         * @param maximumSize The maximum size in bytes
         */
        public void setMaximumSize(Long maximumSize) {
            this.maximumSize = maximumSize;
        }
    

    上传文件允许的后缀名

    在如下的struts.xml中,配置如下:

    <action name="up" class="com.thc.action.UploadAction" method="uploadFile">
            <result name="input">/error.jsp</result>
            <interceptor-ref name="fileUpload">
                <!--设置上传文件允许的后缀名,多个使用逗号隔开  -->
                <param name="allowedExtensions">avi,txt</param>
            </interceptor-ref>
            <!-- 配置了其他的拦截器,就需要手动导入默认的拦截器 -->
            <interceptor-ref name="defaultStack"></interceptor-ref>
    </action>
    

    设置了只允许上传后缀名为avi,txt结尾的文件

    实验上传一个.doc后缀名的文件

    浏览器上会有如下的报错信息 :提示了doc后缀名是不允许的.

    File extension not allowed: upload "测试.doc" "upload_7cd79feb_ad18_40cb_a401_f74b2d2f27a1_00000000.tmp" application/msword

    多文件的上传

    新建一个multipload.jsp的页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <h2>多文件的上传</h2>
        <form action="${pageContext.request.contextPath}/multiup" method="post" enctype="multipart/form-data">
        <input type="file" name="upload"><br/>
        <input type="file" name="upload"><br/>
        <input type="file" name="upload">
        <input type="submit" value="上传">
        </form>
    </body>
    </html>
    

    设置了三个文件上传框

    新建一个MultiUploadAction

    在原来的属性中,把FIle设置为List集合,或者是数组.

    以下为设置了数组.遍历每一个数组的元素.通过索引获取数组的文件名和文件.

    public class MultiUploadAction extends ActionSupport {
    
        private File[] upload;//定义一个File ,变量名要与jsp中的input标签的name一致
        private String[] uploadContentType;//上传文件的mimeType类型
        private String[] uploadFileName;//上传文件的名称
    
        public File[] getUpload() {
            return upload;
        }
        public void setUpload(File[] upload) {
            this.upload = upload;
        }
        public String[] getUploadContentType() {
            return uploadContentType;
        }
        public void setUploadContentType(String[] uploadContentType) {
            this.uploadContentType = uploadContentType;
        }
        public String[] getUploadFileName() {
            return uploadFileName;
        }
        public void setUploadFileName(String[] uploadFileName) {
            this.uploadFileName = uploadFileName;
        }
    
        public void uploadFile(){
            //在WebContent下新建一个upload的文件夹,获取其在服务器的绝对磁盘路径
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            try {
                for (int i = 0; i < upload.length; i++) {
                    //创建一个服务器端的文件
                    File dest = new File(path,uploadFileName[i]);
                    //完成文件上传的操作
                    FileUtils.copyFile(upload[i], dest);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    以下是List集合的方式

    通过list.size()来控制集合的遍历,通过get(index)来获取集合的每一个元素

    public class MultiUploadAction extends ActionSupport {
    
        private List<File> upload;//定义一个File ,变量名要与jsp中的input标签的name一致
        private List<String> uploadContentType;//上传文件的mimeType类型
        private List<String> uploadFileName;//上传文件的名称
    
        public List<File> getUpload() {
            return upload;
        }
        public void setUpload(List<File> upload) {
            this.upload = upload;
        }
        public List<String> getUploadContentType() {
            return uploadContentType;
        }
        public void setUploadContentType(List<String> uploadContentType) {
            this.uploadContentType = uploadContentType;
        }
        public List<String> getUploadFileName() {
            return uploadFileName;
        }
        public void setUploadFileName(List<String> uploadFileName) {
            this.uploadFileName = uploadFileName;
        }
    
        public void uploadFile(){
            //在WebContent下新建一个upload的文件夹,获取其在服务器的绝对磁盘路径
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            try {
                for (int i = 0; i < upload.size(); i++) {
                    //创建一个服务器端的文件
                    File dest = new File(path,uploadFileName.get(i));
                    //完成文件上传的操作
                    FileUtils.copyFile(upload.get(i), dest);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    在配置文件中新建一个action的配置

    <action name="multiup" class="com.thc.action.MultiUploadAction" method="uploadFile">
            <result name="input">/error.jsp</result>
    </action>
    

    多文件上传的测试

    在服务器中部署项目,访问multipload.jsp页面

    选择三个小于2M的文件进行选择文件上传测试.点击上传后,成功在服务器的upload文件夹下上传了文件

    注解开发

    注解配置文件上传

    • 注解的方式配置action类 单个的文件上传
    • 在class 上配置namespace 和parentPackage
    • 注意单文件的上传@ParentPackage的值为"upload_demo",因为在struts.xml设置了拦截器,起了包名为"upload_demo"
    • 在方法上配置@Action @InterceptorRef @Result
    @Namespace("/")
    @ParentPackage("upload_demo")
    public class UploadAction extends ActionSupport {
        private File upload;//定义一个File ,变量名要与jsp中的input标签的name一致
        private String uploadContentType;//上传文件的mimeType类型
        private String uploadFileName;//上传文件的名称
        public File getUpload() {
            return upload;
        }
        public void setUpload(File upload) {
            this.upload = upload;
        }
        public String getUploadContentType() {
            return uploadContentType;
        }
        public void setUploadContentType(String uploadContentType) {
            this.uploadContentType = uploadContentType;
        }
        public String getUploadFileName() {
            return uploadFileName;
        }
        public void setUploadFileName(String uploadFileName) {
            this.uploadFileName = uploadFileName;
        }
    
        @Action(value="up",interceptorRefs={@InterceptorRef("myStack")},results={@Result(name="input",location="/error.jsp")})
        public void uploadFile(){
            try {
                //在WebContent下新建一个upload的文件夹,获取其在服务器的绝对磁盘路径
                String path = ServletActionContext.getServletContext().getRealPath("/upload");
                //创建一个服务器端的文件
                File dest = new File(path,uploadFileName);
                //完成文件上传的操作
                FileUtils.copyFile(upload, dest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 注解的方式的配置多文件的上传

      @Namespace("/")
      @ParentPackage("struts-default")
      public class MultiUploadAction extends ActionSupport {
      
        private List<File> upload;//定义一个File ,变量名要与jsp中的input标签的name一致
        private List<String> uploadContentType;//上传文件的mimeType类型
        private List<String> uploadFileName;//上传文件的名称
      
        public List<File> getUpload() {
            return upload;
        }
        public void setUpload(List<File> upload) {
            this.upload = upload;
        }
        public List<String> getUploadContentType() {
            return uploadContentType;
        }
        public void setUploadContentType(List<String> uploadContentType) {
            this.uploadContentType = uploadContentType;
        }
        public List<String> getUploadFileName() {
            return uploadFileName;
        }
        public void setUploadFileName(List<String> uploadFileName) {
            this.uploadFileName = uploadFileName;
        }
        @Action(value="multiup",results={@Result(name="input",location="/error.jsp")})
        public void uploadFile(){
            //在WebContent下新建一个upload的文件夹,获取其在服务器的绝对磁盘路径
            String path = ServletActionContext.getServletContext().getRealPath("/upload");
            try {
                for (int i = 0; i < upload.size(); i++) {
                    //创建一个服务器端的文件
                    File dest = new File(path,uploadFileName.get(i));
                    //完成文件上传的操作
                    FileUtils.copyFile(upload.get(i), dest);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
      }
      

      ```

    • struts.xml中的内容如下

      <struts>
        <!--配置开发者模式,可以显示更加详细的错误信息 -->
        <constant name="struts.devMode" value="true"></constant>
        <constant name="struts.multipart.maxSize" value="20971520"></constant>
        <package name="upload_demo" extends="struts-default" namespace="/" >
            <interceptors>
                <interceptor-stack name="myStack">
                    <interceptor-ref name="fileUpload">
                        <!--设置上传文件允许的后缀名,多个使用逗号隔开  -->
                        <param name="allowedExtensions">avi,txt</param>
                    </interceptor-ref>
                    <!-- 配置了其他的拦截器,就需要手动导入默认的拦截器 -->
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
        </package>
      </struts>
      

    总结

    • 相比较于使用单纯的javaweb开发FileUpload来实现文件上传,使用Struts2框架的文件上传更加的简洁方便,相关的文件上传的控制也更加的方便.但需要对Struts2框架有所熟悉,才能灵活的运用Strust2的文件上传功能.
    展开全文
  • JAVAEE真实课堂系列之Struts2框架

    千人学习 2017-06-10 10:09:22
    本课程主要讲解Struts2框架的基本用法,其中包括Struts2的入门,基本配置,struts.xml的详细配置,struts的执行流程,并包含多个struts2的案例实现过程
  • Struts2 框架学习

    2017-03-22 14:45:17
    Struts2 框架学习
  • struts2框架详解

    2017-07-06 21:56:01
    一、struts2简介 Struts2是一个基于MVC设计模式的Web应用框架,它本质上...Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。 其全新的Struts 2的体系结构与Strut
  • Struts2框架 简单介绍

    2018-06-28 09:24:02
    1.什么是Struts2框架? Struts2框架是用来替代servlet和jsp 他的功能就是访问服务器的请求、 2.Struts2框架的优点1. 接受参数(能自动封装)2. 参数的校验3. 可以控制页面的跳转4. 可以防止表单的数据重复提交5. ...
  • struts2框架简介

    千次阅读 2018-03-27 20:19:46
    一.struts2框架的开发准备 1.介绍 struts2是实现的MVC模式的JavaEE企业级的轻侵入性.轻量级的表现层web开源框架,提供了开发,发布,到维护过程中的支持. 2.需要资源下载 在apache的官网开开源软件中进行下载...
  • Java struts2 框架

    千次阅读 2015-01-22 22:56:07
    Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理...
  • 初识Struts2框架

    2015-06-13 10:44:38
    Struts2框架结构入门了解
  • 安装Struts2框架

    2017-04-06 17:11:29
    安装Struts2框架   1、打开http://struts.apache.org/网站,点击右上角的struts2,在进入的页面点击Download Now,下载Full Distribution(完整版),并解压。   2、复制lib目录下的commons-logging-1.0.4.jar...
  • struts2框架的总结

    千次阅读 2017-09-04 10:22:37
    struts2框架的学习心得  经过一段时间的学习,逐渐学会了java的一些框架,想在这里做个总结,可能有一些不足之处,日后补充。 一、struts2框架的历史  struts2框架是由apache基金会研发的一种开源框架,但是并不...
  • Struts2入门第一讲——Struts2框架的快速入门

    千次阅读 多人点赞 2017-03-26 00:56:48
    Struts2框架的概述Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中。目前掌握Struts2框架几乎成为Web开发者的必备技能之一。接下来将针对...
  • struts2框架配置文件详解

    千次阅读 2018-06-26 20:40:02
    struts2框架的配置详解
  • Struts 2框架介绍

    千次阅读 热门讨论 2014-04-27 10:59:04
    在我的前一篇博客你是否混谈MVC和三层>>层介绍过MVC模式,既然了解了...优秀的设计思想为基础,吸收了Struts1的部分优点,建立了一个兼容WebWork和Struts1的框架,实现了MVC设计模式.Struts2是Struts的下一代产品,它在Str
  • Struts2框架实现图书管理系统

    千次阅读 2018-11-07 13:04:07
    Struts2框架实现图书管理系统 本篇文章主要介绍使用Struts2框架实现图书管理系统的过程,不足之处还请多多提出。 1、首先最基础的是搭建Struts2框架,在框架的基础上完成图书管理系统。 框架的搭建过程这里不做...
  • Struts2框架是应用最广泛的web框架之一。
  • Struts2框架完成登录操作案例

    千次阅读 2018-02-22 22:17:04
    在这个案例中,我们要使用struts2框架怎样解决  重点: struts2框架如何完成原来由servlet完成的工作。 Struts2框架如何完成请求参数的封装处理 Struts2框架如何完成页面跳转。   简单登录案例原型 ...
  • Struts2框架的见解

    2016-07-05 11:50:14
    Struts2框架的见解本篇文章是我在整理struts2框架的详细内容时的一些见解.适合有一定的struts2开发经验的朋友们互相交流. 一:Struts2的运行原理 在 WEB 容器启动的时候加载 web.xml 文件, 核心控制器 ...
  • 基于Struts2框架的名片管理系统

    千次阅读 2020-10-02 13:55:45
    本篇博文将分享一款基于Struts2框架的名片管理系统,JSP引擎为Tomcat9.0,数据库采用的是MySQL5.5,集成开发环境为Eclipse IDE for Java EE Developers。 名片管理系统主要包括用户管理和名片管理功能。用户功能...
  • Struts2框架搭建及实例

    千次阅读 热门讨论 2015-07-29 08:51:54
    Struts2其实并不是一个陌生的Web框架,Struts2是以Webwork...Struts2框架是一个轻量级的MVC流程框架,轻量级是指程序的代码不是很多,运行时占用的资源不是很多,MVC流程框架就是说它是支持分层开发,控制数据的流程。
  • Struts2框架学习(一)

    万次阅读 多人点赞 2014-03-20 23:30:39
    1,Struts2框架介绍  Struts2框架是MVC流程框架,适合分层开发。框架应用实现不依赖于Servlet,使用大量的拦截器来处理用户请求,属于无侵入式的设计。     2,Struts2框架的流程原理 1)请求先到达...
  • Struts2框架进阶(一)

    千次阅读 2016-10-01 13:40:30
    Struts2框架入门之后,我们就要踏上Struts2框架漫漫的进阶之路了。我们以Struts2框架入门中的案例开始吧!Struts2框架中Action名称的搜索顺序假设某用户的请求路径的URL是...
  • Struts2框架中的 struts.xml文件中如何配置中文乱码的解决方案
  • 学习struts2框架的疑惑

    2017-04-07 06:26:59
    我丝毫感受不到struts2框架的好处,求指点一下,这个东西在实际开发中的用处是什么,能举个例子吗 谢谢了
  • Struts2框架xml验证

    千次阅读 2016-11-29 15:17:47
    struts2框架验证(xml方式) 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法创建一个xml格式验证文件:命名方式:ActionClassName-validation.xml,ActionClassName指...
  • Java Web之Struts2框架

    千次阅读 2018-08-15 08:33:52
    Java Web之Struts2框架     1. 为什么要使用Struts2框架?  传统的servlet/JSP实现的MVC架构,其运行机制是:JSP页面(视图view)发送消息到servlet(控制器Controller),servlet获取请求数据,处理业务...
  • struts2框架流程

    2012-10-18 12:44:21
    Struts2的体系与Struts1体系的差别非常大,因为Struts2使用了WebWork的设计核心,而不是Struts1的设计... Struts2框架的大概处理流程如下:  1、加载类(FilterDispatcher)  2、读取配置(struts配置文件中的Action
  • Struts2框架工作流程以及配置

    千次阅读 2017-02-27 15:53:28
    什么是Struts2框架 是一个基于MVC设计模式的web应用框架,相当于一个servlet,相当于MVC中的C层(controller)。它的前身是webwork,控制器应用框架,可以优化对C层的操作。 三.Struts2框架配置 1.下载Struts2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,815
精华内容 12,326
关键字:

struts2框架