Struts如何使用多模块和扩展

1.多模块

许多规模庞大的系统,可能需要许多的模块,比如财务模块、客服模块、销售模块等等。一个struts-config文件就会显得十分乏力,那要如何配置多模块呢。

配置方法
  1. 建立单独的struts配置文件

  2. 在web.xml里面配置相应信息

    2.1 增加一个参数名称为“config/模块名” 的参数,指明另一模块配置文件的文件路径

    2.2 模块名称和目录名称需要一样

    2.3

<init-param>
	<param-name>config/submodule</param-name>
	<param-value>WEB-INF/2.xml</param-value>
</init-param>

假设我们在一个大型商场系统里面设置了多个模块,除了默认的struts-congfig.xml,还有一个我们自己定义的struts-config-sale.xml,我们需要在web.xml中进行配置,代码如下:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <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>

        <init-param>
            <param-name>config/sale</param-name>
            <param-value>/WEB-INF/struts-config-sale.xml</param-value>
        </init-param>

        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

假设我们在struts-config.xml和struts-config-sale.xml中都设置名为"/query"的action,当我们在地址栏输入query.do的时候,系统是默认访问struts-config.xml中的query,如果想要让系统访问struts-config-sale.xml中的query,则需要在地址栏中增加"/sale",也就是模块在web.xml
中配置的名称。

struts-config.xm:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryForm" type="ActionForm.QueryForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryForm" type="Action.QueryAction"></action>
    </action-mappings>
</struts-config>

struts-config-sale.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryInSaleForm" type="ActionForm.QueryInSaleForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryInSaleForm" type="Action.QueryInSaleAction"></action>
    </action-mappings>
</struts-config>

QueryAcion.java:

package Action;

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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class QueryAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("在默认模块内");
        return null;
    }
}

QueryInsaleAcion.java:

package Action;

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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class QueryInSaleAction extends Action {
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("在销售模块内");
        return null;
    }
}

这里看出来,两个Action都只打印了一句话——在默认模块内还是在销售模块内,当我们在地址栏输入query.do的时候,控制台会输出:
在这里插入图片描述

当我们在地址栏加上"/sale"后,控制台会输出:

在这里插入图片描述

切换方法1:使用链接切换

用html:link指定module(模块路径)和page(.do 文件路径)名称

    <html:link page="/页面" module="/模块名称"></html:link>

如果想要在页面上通过点击链接到达不同的模块,可以选择两种不同的方式,一种是在action里面像地址栏一样的输入具体路径,还有一种是在module里面填写模块名称,代码如下:

p1.jsp

<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<%--
  Created by IntelliJ IDEA.
  User: air
  Date: 2019-08-17
  Time: 18:33
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>选取模块</title>
</head>
<body>
<html:link action="/query.do">默认模块</html:link><br/>
<html:link action="/query.do" module="/">默认模块</html:link><br/>
<html:link action="/sale/query">销售模块</html:link><br/>
<html:link action="/query" module="/sale">销售模块</html:link>
</body>
</html>

效果如下:
在这里插入图片描述

在这里插入图片描述
可以看到,两种方法都是在控制台内输出响应的信息。

切换方法2:SwitchAction

在指定模块中声明一个action,此action的type为org.apache.struts.actions.SwitchAction,然后利用:

切换:/actionPath?prefix=/模块名&page=/页面名

<action path="/switch" type="org.apache.struts.actions.Switch Action" />
<html:link action="/switch.do?prefix=/submodule&page=/subJsp.jsp">链接</html:link>

struts-config-sale.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryForm" type="ActionForm.QueryForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryForm" type="Action.QueryAction"></action>
        <action path="/switch" type="org.apache.struts.actions.SwitchAction"></action>
    </action-mappings>
</struts-config>

p1.jsp:

<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<%--
  Created by IntelliJ IDEA.
  User: air
  Date: 2019-08-17
  Time: 18:33
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
    <title>选取模块</title>
</head>
<body>
<html:link action="/query.do">默认模块</html:link><br/>
<html:link action="/query.do" module="/">默认模块</html:link><br/>
<html:link action="/sale/query">销售模块</html:link><br/>
<html:link action="/query" module="/sale">销售模块</html:link><br/>
<%--利用SwitchAction切换--%>
<html:link action="/switch.do?prefix=/sale&page=/query.do">销售模块</html:link>
</body>
</html>

效果和其余两种是一样的,如果想通过这种方式达到默认模块,只需要删除"/sale"即可。

2.插件开发

如果我们希望Struts框架在启动的时候就自动做一些初始化的工作,利用什么方案比较好呢?

传统方法:

  1. 过滤器(服务器启动时自动运行一次init,以后每一次提交都运行一次doFilter)

新建一个过滤器,并且在web.xml中配置一下:

Filters.Fliter1.java:

package Filters;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(filterName = "Filter")
public class Filter1 implements Filter {
    public void destroy() {
        System.out.println("过滤器destroy");

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("过滤器DoFilter");
        chain.doFilter(req,resp);
    }

    public void init(FilterConfig config) throws ServletException {
    System.out.println("过滤器启动");
    }

}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>Filter1</filter-name>
        <filter-class>Filters.Filter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Filter1</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <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>

        <init-param>
            <param-name>config/sale</param-name>
            <param-value>/WEB-INF/struts-config-sale.xml</param-value>
        </init-param>

        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

然后启动服务器,可以看到服务器在第一次启动的时候,init方法会被调用。每次提交一次请求的时候,DoFliter方法都会被调用一次。但是过滤器的功能太庞大了,Struts一向以小巧灵活著称,所以Struts提供了一个插件的方法,可以实现相同的功能。

  1. 让Struts启动的时候, 向application内放入一个内容。

一般方法:插件

  1. 建立一个类,实现org.apache.struts.action.PlugIn接口
  2. 编写方法,注意Servlet参数,用处很大
  3. 配置插件:
<plug-in className=" "></plug-in>

PlugIn.plugin1.java:

package PlugIn;

import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

import javax.servlet.ServletException;

public class plugin1 implements PlugIn {

    @Override
    public void destroy() {
        System.out.println("插件destroy");
    }

    @Override
    public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
        System.out.println("插件初始化");
    }
}

struts-config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryForm" type="ActionForm.QueryForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryForm" type="Action.QueryAction"></action>
        <action path="/switch" type="org.apache.struts.actions.SwitchAction"></action>
    </action-mappings>
    <plug-in className="PlugIn.plugin1"></plug-in>
</struts-config>

当我们启动服务器的时候,过滤器初始化,然后插件初始化。

在插件中,可以看到重写的init方法的参数里面有一个ActionServlet,说明插件是可以和Servlet坐一起操作,比如获取Servlet里面的信息。同样,插件也可以获取配置文件中的信息。比如做一个插件,检查某文件的字符编码是什么,就可以利用插件从配置文件里面去查找。

在插件类里面创建一个JavaBean风格的私有成员,然后在web.xml里面配置属性即可,代码如下:

plugin.java:

package PlugIn;

import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

import javax.servlet.ServletException;

public class plugin1 implements PlugIn {
    private String value1;

    @Override
    public void destroy() {
        System.out.println("插件destroy");
    }

    @Override
    public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
        System.out.println("插件初始化");
    }

    public String getValue1() {
        return value1;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }
}

struts-config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryForm" type="ActionForm.QueryForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryForm" type="Action.QueryAction"></action>
        <action path="/switch" type="org.apache.struts.actions.SwitchAction"></action>
    </action-mappings>
    <plug-in className="PlugIn.plugin1">
        <set-property property="value1" value="welcome"></set-property>
    </plug-in>
</struts-config>

注意:在配置文件中可以通过设置属性来影响插件的行为

插件和过滤器的区别

插件:只是负责初始化

过滤器:功能齐全

二者都会在服务器启动的时候自动初始化,如果是一个较大的系统,这样会耗费大量资源,二者没有什么区别。过滤器的初始化顺序高于插件的初始化顺序,过滤器的功能比较多,插件无法做到过滤的功能,过滤器无法访问Struts里面的功能,而插件可以。

看上去过滤器的功能的确比较齐全,所以需要一个新的扩展来专门负责过滤功能,和插件联合起来使用,大致上可以比得上过滤器的功能。

3.扩展

如果希望在表单处理之前,让Struts做一些事情,相当于一个过滤功能,应该用什么方法?

传统方法:过滤器,但是缺陷是不可以访问struts对象。

而RequestProcessor类可以实现这种拓展:

Struts运行时,提交到ActionServlet,底层实际上是调用RequestProcessor来完成工作的:

那我们知道了这个底层的知识后,我们先一步继承RequestProcessor类,然后重写方法,就相当于可以在Struts被提交前做一些操作

  1. 建立一个类,继承org.apache.struts.action.RequestProcessor
  2. 编写方法,注意需要重写方法processPreprocess,注意返回值
  3. 配置控制器:
<controller processorClass="extendsevlet.CProcessor"></controller>

具体代码如下:
Filters.Filter2.java:

package Filters;

import org.apache.struts.action.RequestProcessor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Filter2 extends RequestProcessor {
    @Override
    protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("Filter2过滤(扩展RequestProcessor)");
        return true;//true表示请求继续向下传递进行处理,false表示不处理请求。
    }
}

这个时候系统还是不认识这个扩展组件的,所以需要在struts-config.xml里面进行配置:

struts-config.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts-config PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
        "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
        <form-bean name="queryForm" type="ActionForm.QueryForm"></form-bean>
    </form-beans>

    <action-mappings>
        <action path="/query" name="queryForm" type="Action.QueryAction"></action>
        <action path="/switch" type="org.apache.struts.actions.SwitchAction"></action>
    </action-mappings>

    <controller processorClass="Filters.Filter2"></controller>


    <plug-in className="PlugIn.plugin1">
        <set-property property="value1" value="welcome"></set-property>
    </plug-in>
</struts-config>

值得一提的是,过滤器可以接受get、post的请求,而扩展的过滤组件则只能接受表单的提交,所以过滤器的功能还是强大一些,当然也可以在扩展组件里面设置其他属性达到想要的目的。

但是扩展组件的优势也是有的,通过上面重写的processPreprocess方法,可以利用this.调用Struts对象,这是过滤器做不到的。

扩展RequestProcessor:默认情况下,只能过滤表单提交

4.小结

插件和扩展的结合使用,虽然比不上过滤器的强大功能,但是也能够勉强满足需求,在项目开发的实际过程中,我们可以根据需求去选择不同的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值