Struts学习笔记


Struts

标签(空格分隔): SSH Struts


一、Struts基本介绍

(1)Struts基本概念

Struts是一个web框架

(2)为什么有struts?

Struts是基于MVC的web框架,解决了MVC设计的规范问题。

(3)Struts的优缺点

优点:
1. 程序更加规范
2. 开发效率提高
3. 程序可读性提高
4. 程序可维护性提高
缺点:
1. form表单优点鸡肋
2. action是单态的(对网站的并发处理有影响)

二、Struts原理

(1)Struts运行原理图

下面以登录验证时序图来举例说明:
这里写图片描述

三、快速入门案例

(1)手动配置Struts

以上图登录为例,步骤如下:
1. 新建web工程,导入struts jar包
2. 创建login.jsp页面
3. 编写ActionForm和Action
4. 编写structs-config.xml文件,用于配置actionform和action的对应关系及跳转,一般放在WEB-INF目录下。
5. 编写welcome.jsp和error.jsp页面
6. 在web.xml中配置ActionServlet
7. 开始使用我们的structs
8. struts中文乱码问题->过滤器

struts-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
       "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
       "http://struts.apache.org/dtds/struts-config_1_3.dtd">   
<struts-config>
<!-- 配置单 -->
<form-beans>
    <!-- type 指明actionform的完整类名 -->
    <form-bean name="userForm" type="com.demo.form.UserForm"/>
</form-beans>
<!-- 配置action -->
<action-mappings>
    <!--name用来关联action和actionform, path指定访问action的路径 (注意斜杠), type指定action类的完整类名 -->
    <!--scope="request" 表示该action对应的表单对象的生命周期request=request.setAttribute("userForm",userForm)
      scope="session" 表示该action对应的表单对象的生命周期session=request.getSession() .setAttribute("userForm",userForm)-->
    <action path="/login" name="userForm" scope="request" type="com.demo.action.LoginAction">
        <!-- 配置页面跳转 -->
        <forward name="success" path="/WEB-INF/welcome.jsp"/>
        <forward name="error" path="/WEB-INF/error.jsp"/>
    </action> 
</action-mappings>
</struts-config>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

UserForm.java

package com.demo.form;
import org.apache.struts.action.ActionForm;
public class UserForm extends ActionForm {
    private static final long serialVersionUID = -5728373396473448952L;
    private String username;
    private String password;
    //保证set和get方法名和前端form中input的name一致
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

LoginActin.java

package com.demo.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.demo.form.UserForm;
public class LoginAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // TODO Auto-generated method stub
        UserForm userForm = (UserForm) form;
        //System.out.println("username : "+userForm.getUsername());
        if(userForm!=null && 
                "lawen".equals(userForm.getUsername()) && 
                "123456".equals(userForm.getPassword())){
            return mapping.findForward("success");
        }
        return mapping.findForward("error");
    }
}

(2) Structs需要注意的细节

struts底层使用到反射机制,因此在配置action和form-bean时type属性必须指明相应类的完整路径,在action类中,setter和getter方法名应该和form表单的属性name一致。actionform scope可选request和session

(3)使用过滤器解决structs 表单中文乱码问题

步骤如下:开发一个过滤器,并设置request,setCharacterEncoding("utf-8");

Filter.java

package com.demo.filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyFilter1 extends HttpServlet implements Filter {
    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
            FilterChain arg2) throws IOException, ServletException {
        // TODO Auto-generated method stub
        arg0.setCharacterEncoding("utf-8"); //设置接收编码
        arg2.doFilter(arg0, arg1); //必须
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  <filter>
    <filter-name>MyFilter1</filter-name>
    <filter-class>com.demo.filter.MyFilter1</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>MyFilter1</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

三、struts-config配置详解

struts-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config.dtd">
<!-- struts-config.xml中的元素必须按照上述doc指令中的dtd文档定义顺序书写,本例即遵从了dtd定义顺序 -->
<!-- struts-config是整个xml的根元素,其他元素必须被包含其内 -->
<struts-config>
<!--
   名称:data-sources
   描述:data-sources元素定义了web App所需要使用的数据源
   数量:最多一个
   子元素:data-source
-->
<data-sources>
   <!--
    名称:data-source
    描述:data-source元素定义了具体的数据源
    数量:任意多个
    属性:
     @key:当需要配置多个数据源时,相当于数据源的名称,用来数据源彼此间进行区别
     @type:可以使用的数据源实现的类,一般来自如下四个库
      Poolman,开放源代码软件
      Expresso,Jcorporate
      JDBC Pool,开放源代码软件
      DBCP,Jakarta
   -->
   <data-source key="firstOne" type="org.apache.commons.dbcp.BasicDataSource">
    <!--
     名称:set-property
     描述:用来设定数据源的属性
     属性:
      @autoCommit:是否自动提交 可选值:true/false
      @description:数据源描述
      @driverClass:数据源使用的类
      @maxCount:最大数据源连接数
      @minCount:最小数据源连接数
      @user:数据库用户
      @password:数据库密码
      @url:数据库url
    -->
    <set-property property="autoCommit" value="true"/>
    <set-property property="description" value="Hello!"/>
    <set-property property="driverClass" value="com.mysql.jdbc.Driver"/>
    <set-property property="maxCount" value="10"/>
    <set-property property="minCount" value="2"/>
    <set-property property="user" value="root"/>
    <set-property property="password" value=""/>
    <set-property property="url" value="jdbc:mysql://localhost:3306/helloAdmin"/>
   </data-source>
</data-sources>
<!--
   名称:form-beans
   描述:用来配置多个ActionForm Bean
   数量:最多一个
   子元素:form-bean
-->
<form-beans>
   <!--
    名称:form-bean
    描述:用来配置ActionForm Bean
    数量:任意多个
    子元素:form-property
    属性:
     @className:指定与form-bean元素相对应的配置类,一般默认使用org.apaceh.struts.config.FormBeanConfig,如果自定义,则必须继承 FormBeanConfig
     @name:必备属性!为当前form-bean制定一个全局唯一的标识符,使得在整个Struts框架内,可以通过该标识符来引用这个ActionForm Bean。
     @type:必备属性!指明实现当前ActionForm Bean的完整类名。
   -->
   <form-bean name="Hello" type="myPack.Hello">
    <!--
     名称:form-property
     描述:用来设定ActionForm Bean的属性
     数量:根据实际需求而定,例如,ActionForm Bean对应的一个登陆Form中有两个文本框,name和password,ActionForm Bean中也有这两个字段,则此处编写两个form-property来设定属性
     属性:
      @className:指定与form-property相对应的配置类,默认是org.apache.struts.config.FormPropertyConfig,如果自定义,则必须继承FormPropertyConfig类
      @name:所要设定的ActionForm Bean的属性名称
      @type:所要设定的ActionForm Bean的属性值的类
      @initial:当前属性的初值
    -->
    <form-property name="name" type="java.lang.String"/>
    <form-property name="number" type="java.lang.Iteger" initial="18"/>
   </form-bean>
</form-beans>
<!--
   名称:global-exceptions
   描述:处理异常
   数量:最多一个
   子元素:exception
-->
<global-exceptions>
   <!--
    名称:exception
    描述:具体定义一个异常及其处理
    数量:任意多个
    属性:
     @className:指定对应exception的配置类,默认为org.apache.struts.config.ExceptionConfig
     @handler:指定异常处理类,默认为org.apache.struts.action.ExceptionHandler
     @key:指定在Resource Bundle种描述该异常的消息key
     @path:指定当发生异常时,进行转发的路径
     @scope:指定ActionMessage实例存放的范围,默认为request,另外一个可选值是session
     @type:必须要有!指定所需要处理异常类的名字。
     @bundle:指定资源绑定
   -->
   <exception
    key="hello.error"
    path="/error.jsp"
    scope="session"
    type="hello.HandleError"/>
</global-exceptions>
<!--
   名称:global-forwards
   描述:定义全局转发
数量:最多一个
   子元素:forward
-->
<global-forwards>
   <!--
    名称:forward
    描述:定义一个具体的转发
    数量:任意多个
    属性:
     @className:指定和forward元素对应的配置类,默认为org.apache.struts.action.ActionForward
     @contextRelative:如果为true,则指明使用当前上下文,路径以“/”开头,默认为false
     @name:必须配有!指明转发路径的唯一标识符
     @path:必须配有!指明转发或者重定向的URI。必须以"/"开头。具体配置要与contextRelative相应。
     @redirect:为true时,执行重定向操作,否则执行请求转发。默认为false
   -->
   <forward name="A" path="/a.jsp"/>
   <forward name="B" path="/hello/b.do"/>
</global-forwards>
<!--
   名称:action-mappings
   描述:定义action集合
   数量:最多一个
   子元素:action
-->
<action-mappings>
   <!--
    名称:action
    描述:定义了从特定的请求路径到相应的Action类的映射
    数量:任意多个
    子元素:exception,forward(二者均为局部量)
    属性:
     @attribute:制定与当前Action相关联的ActionForm Bean在request和session范围内的名称(key)
     @className:与Action元素对应的配置类。默认为org.apache.struts.action.ActionMapping
     @forward:指名转发的URL路径
     @include:指名包含的URL路径
     @input:指名包含输入表单的URL路径,表单验证失败时,请求会被转发到该URL中
     @name:指定和当前Acion关联的ActionForm Bean的名字。该名称必须在form-bean元素中定义过。
     @path:指定访问Action的路径,以"/"开头,没有扩展名
     @parameter:为当前的Action配置参数,可以在Action的execute()方法中,通过调用ActionMapping的getParameter()方法来获取参数
     @roles:指定允许调用该Aciton的安全角色。多个角色之间用逗号分割。处理请求时,RequestProcessor会根据该配置项来决定用户是否有调用该Action的权限
     @scope:指定ActionForm Bean的存在范围,可选值为request和session。默认为session
     @type:指定Action类的完整类名
     @unknown:值为true时,表示可以处理用户发出的所有无效的Action URL。默认为false
     @validate:指定是否要先调用ActionForm Bean的validate()方法。默认为true
    注意:如上属性中,forward/include/type三者相斥,即三者在同一Action配置中只能存在一个。
   -->
   <action path="/search"
    type="addressbook.actions.SearchAction"
    name="searchForm"
    scope="request"
    validate="true"
    input="/search.jsp">
    <forward name="success" path="/display.jsp"/>
   </action> 
</action-mappings>
<!--
   名称:controller
   描述:用于配置ActionServlet
   数量:最多一个
   属性:
    @bufferSize:指定上传文件的输入缓冲的大小.默认为4096
    @className:指定当前控制器的配置类.默认为org.apache.struts.config.ControllerConfig
    @contentType:指定相应结果的内容类型和字符编码
    @locale:指定是否把Locale对象保存到当前用户的session中,默认为false
    @processorClass:指定负责处理请求的Java类的完整类名.默认org.apache.struts.action.RequestProcessor
    @tempDir:指定文件上传时的临时工作目录.如果没有设置,将才用Servlet容器为web应用分配的临时工作目录.
    @nochache:true时,在相应结果中加入特定的头参数:Pragma ,Cache-Control,Expires防止页面被存储在可数浏览器的缓存中,默认为false
-->
<controller 
   contentType="text/html;charset=UTF-8"
   locale="true"
   processorClass="CustomRequestProcessor">
</controller>
<!--
   名称:message-resources
   描述:配置Resource Bundle.
   数量:任意多个
   属性:
    @className:指定和message-resources对应的配置类.默认为org.apache.struts.config.MessageResourcesConfig
    @factory:指定资源的工厂类,默认为org.apache.struts.util.PropertyMessageResourcesFactory
    @key:
    @null:
    @parameter:
-->
<message-resources
   null="false"
   parameter="defaultResource"/>
<message-resources
   key="images"
   null="false"
   parameter="ImageResources"/>
<!--
   名称:plug-in
   描述:用于配置Struts的插件
   数量:任意多个
   子元素:set-property
   属性:
    @className:指定Struts插件类.此类必须实现org.apache.struts.action.PlugIn接口
-->
<plug-in
   className="org.apache.struts.validator.ValidatorPlugIn">
   <!--
    名称:set-property
    描述:配置插件的属性
    数量:任意多个
    属性:
     @property:插件的属性名称
     @value:该名称所配置的值
   -->
   <set-property 
    property="pathnames"
    value="/WEB-INF/validator-rules.xml,/WEB-INF/vlaidation.xml"/>
</plug-in>
</struts-config>
一、为struts配置web.xml 
1,配置ActionServlet(only one),使其接收应用程序收到的所有请求 
分为两步,a:使用servlet元素配置servlet实例,做servlet-mapping 
<web-app> 
<servlet> 
<servlet-name>storefront</servlet-name> 
<servlet-class>完全限定的类名</servlet-class> 
</servlet> 
<servlet-mapping> 
<servlet-name>storefront</servlet-name> 
<url-pattern>*.do</url-pattern> 
</servlet-mapping> 
</web-map> 
2,配置初始化参数:init-param,以name/value表示<param-name><param-value> 
config :默认为/WEB-INF/struts-config.xml 
config/sub1:config/... 从附加的struts配置文件中加在资程序sub1 
debug:servlet的调试detail 
detail:Digester的调试detail 
convertHack 
3,<taglib>使用struts提供的标记库时必须配置包括 
<taglib-uri>识别web应用程序所使用的标记库,必须是有效的 
<taglib-location>指定了标记库描述文件的位置 
4,<welcome-file-list>配置在web app中输入有效的,但不完整的url所使用的default resource;不使用servlet映射 
<welcome-file>起始和结束都没有/符号 
5,<error-page> 
(<error-code> <location>) 
<<exception-type><location> 
</error-page>
二、Struts配置文件 
ApplicationConfig: 包含了struts配置文件中的所有信息 
1, <data-source> 
<set-property property=““ value=““/> 
<data-source> 
2,<form-beans> 
<form-bean name=“loginForm“ type=“完全限定的类名,是ActionForm的子类“> 
<form-property name=““ type=““/> 
</form-bean> 
<form-bean 
</form-beans> 
3,<global-exceptions> 
4,<global-forwards>
在Struts1.3中已经取消了<data-sources>标签,也就是说只能在1.2版中配置,因为Apache不推荐在struts-config.xml中配置数据源。所以建议不要在struts中配置数据源,如果你用了hibernate或spring得话就可以在hibernate配置文件或spring文件配数据源如果都没用就到tomcat中配置  

四、JSTL标签库(JSP Standard Tag Libaray)

域对象优先级:pageContext > request > session > application

五、Struts标签

(1)HTML标签

(2)bean标签

(3)logic标签

六、Struts文件上传及下载

(1)上传

upload.jsp

 <form action="/structs1/login.do" method="post" enctype="multipart/form-data">
       photo: <input type="file" name="photo"><br>
       <input type="submit" value="上传">
   </form>

UserForm

package com.demo.form;

import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;

public class UserForm extends ActionForm {

    private static final long serialVersionUID = -5728373396473448952L;
    private FormFile photo;
    //保证set和get方法名和前端form中input的name一致
    public FormFile getPhoto() {
        return photo;
    }
    public void setPhoto(FormFile photo) {
        this.photo = photo;
    }   
}

uploadAction

package com.demo.action;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import com.demo.form.UserForm;
/*action是单态的*/
public class LoginAction extends Action {

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // TODO Auto-generated method stub
        UserForm userForm = (UserForm) form;
        FormFile photoFile = userForm.getPhoto();
        System.out.println("filename : "+photoFile.getFileName()+" filesize:"+
                photoFile.getFileSize());
        String path=this.getServlet().getServletContext().getRealPath("file");
        System.out.println(path+"\\"+photoFile.getFileName());
        OutputStream out=null;
        InputStream in = null;
        try {
            in = photoFile.getInputStream();
            out = new FileOutputStream(path+"\\"+photoFile.getFileName());
            byte buff[] = new byte[1024];
            int len = 0;
            while((len=in.read(buff))>0){
                out.write(buff, 0, len);
            }
            System.out.println("文件保存成功");
        } catch (Exception e) {
            // TODO: handle exception
            return mapping.findForward("error");
        }finally{
            if(out!=null)
                out.close();
            if(in!=null)
                in.close();
        }
        return mapping.findForward("success");
    }
}

(4)下载

downloadAction

response.setHeader("Content-Disposition", "attachment;filename=test.pdf");
//获取要下载文件的全路径
String path = this.getServletContext().getRealPath("/images/test.pdf");
//创建文件流
FileInputStream in = new FileInputStream(path);
byte buff[] = new byte[1024];
int len = 0;
OutputStream out = response.getOutputStream();
while((len=in.read(buff))>0){
    out.write(buff, 0, len);
}
in.close();
out.close();

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *