Struts2零配置之Configuration by Convention(一)

本文介绍Struts2使用convention-plugin实现零配置的方法。通过约定大于配置的原则,简化struts.xml文件,使开发者仅需关注业务逻辑。文章详细解释了类名到URL的映射规则、结果页面的位置约定等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        随着struts2的不断升级,Struts开始使用convention-plugin代替codebehind-plugin来实现struts的零配置。所谓的零配置并不是任何配置都不需要,而是采用约定大于配置的方式。

在web开发过程中,根据convention-plugin的默认约定,我们不再需要在Struts.xml中配置任何信息。

首先,让我们先来看一下基于convention-plugin实现的Struts"零配置"的HelloWorld。


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>
	<package name="default" namespace="/" extends="struts-default" />
</struts>

我的HelloWorld


package com.example.actions;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport {

    private static final long serialVersionUID = -6662538623355755690L;

    private String message;

    public String getMessage() {
        return message;
    }

    public String execute() {
        if (System.currentTimeMillis() % 2 == 0) {
            message = "It's 0";
            return "zero";
        }

        message = "It's 1";
        return SUCCESS;
    }
}

对于一个简单的HelloWorld来讲,struts.xml里面的配置简直精简到了极致。不需要再写一堆一堆的<action>配置了。而我们需要做的只是加入一个struts2-convention-plugin-x.x.x.x.jar

之所以在HelloWorld中不需要任何配置,是因为struts2-convention-plugin进行了以下一系列的约定。

  • Action location by package naming conventions
    com.example.action.MainAction
    com.example.actions.products.Display (implements com.opensymphony.xwork2.Action)
    com.example.struts.company.details.ShowCompanyDetailsAction
    com.example.struts2.company.details.ShowCompanyDetailsAction

          Convention plugin默认将包路径包含action,actions,struts,struts2的所有包都作为Action类的路径来搜索。你可以通过设置struts.convention.package.locators属性来修改这个配置。Convention plugin默认的配置如下:

<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>

Convention plugin在上述的包及其子包中查找后缀为Action、或者实现了com.opensymphony.xwork2.Action的类。你可以通过设置

struts.convention.action.suffix属性来修改这个配置。Convention plugin默认的配置如下:

<constant name="struts.convention.action.suffix" value="Action"/>

  • Result (JSP, FreeMarker, etc) location by naming conventions

          当在浏览器中输入http://localhost:8080/hello-world访问时,页面会跳转到WEB-INF/content/hello-world.jsp。
          默认情况下, Convention plugin假设所有的results存放在WEB-INF/content/下。可以通过设置struts.convention.result.path进行修改。Convention plugin默认的配置如下:

<constant name="struts.convention.result.path" value="/WEB-INF/content/"/>

          Convention plugin即使在找不到对应的action的情况下,也可以通过Action的URL(这里是/hello-world)找到对应的结果(/hello-world.jsp)。

  • Class name to URL naming convention
          com.example.actions.MainAction -> /main
          com.example.actions.products.Display -> /products/display

          com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details/show-company-details

          com.example.struts.company.details.ShowCompanyDetailsAction对应的Action URL为例,Convention plugin会将com.example.struts.company.details.ShowCompanyDetailsAction 的struts后的子包转换成命名空间“/company/details/”,然后ShowCompanyDetailsAction中的“Action”后缀去掉,并将驼峰式的命名大写变小写,并在之间加上“-”(当然“-”也是Convention plugin默认的)最终形成/company/details/show-company-details。这就是类名和Action URL之间的“约定”。


  • Package name to namespace convention
          com.example.actions.MainAction -> /
          com.example.actions.products.Display -> /products

          com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details

          Convention plugin默认将actions、actionstruts、struts2作为root Package,那么com.example.actions.MainAction的命名空间即为“/”,而com.example.actions.products.Display的命名空间为“/products”。


              正是有了这些“约定”才使得我们的HelloWorld能够实现零配置。

          实际的开发过程中如果只这些约定,也许不能完全满足实际项目的需要幸运的是Convention Plugin的配置是相当灵活的。

日后,在继续学习基于注解的灵活配置。

<?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id: struts-plugin.xml 722219 2008-12-01 20:41:26Z musachy $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <bean class="com.inc.sbu.view.FreeMarkerPageFilter" static="true" optional="true"/> <constant name="struts.ognl.allowStaticMethodAccess" value="true" /> <constant name="struts.convention.relative.result.types" value="freemarker,dispatcher"/> <constant name="struts.convention.action.mapAllMatches" value="true"/> <constant name="struts.convention.package.locators" value="web,action" /> <constant name="struts.convention.default.parent.package" value="yk-default"/> <constant name="struts.convention.result.path" value="/pages"/> <constant name="struts.convention.result.flatLayout" value="true"/> <constant name="struts.i18n.encoding" value="gbk" /> <constant name="struts.i18n.reload" value="false" /> <constant name="struts.devMode" value="false" /> <constant name="struts.serve.static.browserCache" value="false"/> <constant name="struts.configuration.xml.reload" value="false" /> <constant name="struts.custom.i18n.resources" value="globalMessages" /> <constant name="struts.freemarker.manager.classname" value="customFreemarkerManager" /> <constant name="struts.multipart.saveDir" value="/tmp"/> <constant name="struts.multipart.maxSize" value="1000000000" /> <constant name="struts.ui.theme" value="simple"/> <constant name="struts.action.extension" value="xhtml,,json" /> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="yk-default" extends="struts-default"> <result-types> <result-type name="jasper" class="org.apache.struts2.views.jasperreports.JasperReportsResult"/> <result-type name="json" class="org.apache.struts2.json.JSONResult"/> </result-types> <interceptors> <interceptor class="com.inc.sbu.struts.AuctionInterceptor" name="auctionInterceptor"/> <interceptor class="com.inc.sbu.struts.TokenInterceptor" name="incTokenInterceptor"/> <interceptor class="com.inc.sbu.struts.WorkFlowInterceptor" name="incFlowInterceptor"/> <interceptor class="com.inc.sbu.util.FileUploadInterceptor" name="fileUploadInterceptor"/> <interceptor class="com.inc.sbu.struts.ClewInterceptor" name="clewInterceptor"/> <interceptor-stack name="bidStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="profiling"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="auctionInterceptor"/> </interceptor-stack> <interceptor-stack name="subStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="profiling"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="fileUploadInterceptor"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,inputxy,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="clewInterceptor"> <param name="excludeMethods">login,loginManager,logout,index</param> </interceptor-ref> <interceptor-ref name="incTokenInterceptor"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="subStack"/> <global-results> <result name="invalid.token">/pages/error/repeat-submit.jsp</result> <result name="clew" type="dispatcher">/pages/clew.jsp</result> <result name="manage-clew" type="dispatcher">/pages/manage-clew.jsp</result> <result name="auction-clew" type="dispatcher">/pages/auction-clew.jsp</result> <result name="syserror" type="dispatcher">/pages/error.jsp</result> <result name="validerror" type="dispatcher">/pages/error.jsp</result> <result name="frontpurviewerror" type="dispatcher">/pages/error/frontpurviewerror.jsp</result> <result name="frontloginerror" type="dispatcher">/pages/error/frontpurviewerror.jsp</result> <result name="fronterror" type="dispatcher">/pages/error/frontticketerror.jsp</result> <result name="filenotfound" type="dispatcher">/pages/error/filenotfound.jsp</result> <result name="login" type="redirect">/login</result> <result name="adminLogin" type="dispatcher">/login.jsp</result> <result name="login" type="redirect">/login</result> <result name="entran" type="redirect">/entran</result> <!-- <result name="adminLogin" type="dispatcher">/login.jsp</result> --> <result name="auctionAdminError" type="redirect">/auction/adminLogin</result> <result name="auctionActorError" type="redirect">/auction/login</result> </global-results> </package> <!-- Overwrite Convention --> </struts> 我现在需要重写fileUpload,即不再使用fileUpload的拦截器,需要怎么配置
最新发布
08-01
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值