Apress Pro Apache Struts with Ajax phần 7 pot

53 415 0
Apress Pro Apache Struts with Ajax phần 7 pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

then begin generating either deployment descriptors, configuration files, or source code based on the XDoclets embedded in the application’s source code. Let’s not forget though that XDoclet is a code generator. Oftentimes when writing up a configuration file, like a web.xml file, you might need to include static content as part of the file being dynamically generated. For instance, a development team using XDoclet might need to configure a servlet contained within a jar file (for example, the Struts ActionServlet). This is where step 4 comes into play. XDoclet allows the development team to define static pieces of a configuration file in what is called a merge point. As an XDoclet Ant Task parses an application’s source file, it will try to locate any merge-point files (the actual merge files are different for each XDoclet Ant Task) and merge the content of these files with the content dynamically generated from the XDoclet tags inside the Java source code. Another use for merge-point files is where you do not want to write Java code for some- thing simple, like setting up a default action in Struts, but you need to make sure that the information is added to the configuration file. For instance, you might want to send users to a JSP page if they try to go to a URL not available in an application. You are not going to write a Struts Action class just for this. Instead, you could place the following <action> definition in a merge-point file called struts-actions.xml: <action path="/foo" unknown="true" forward="/WEB-INF/foo.jsp"/> The combination of static and dynamic text results in the output of a Java source file, con- figuration file, or deployment descriptor. ■Note Remember that XDoclet does not just generate configuration files. Several XDoclet tags (for exam- ple, < ejbdoclet >) actually generate source code. There are even instances where that generated source code can include source from a merge-point file. If the output is Java source code, the Ant script can compile the source. If the output is a configuration file or a deployment descriptor, the Ant script can then package it and deploy it as a jar, war, or ear file. We have now walked you through the conceptual process of using XDoclet. Let’s revisit the web filter example used earlier in the chapter. We will explore in greater detail • The available XDoclet tags • The anatomy of an XDoclet tag •Setting up and configuring Ant to parse and process XDoclet tags After we go through this explanation, we will start looking at the Struts XDoclet tags. CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET296 Ch08_7389_CMP3 9/28/06 8:42 PM Page 296 The Available XDoclet Tags The number of XDoclet markup tags and the corresponding functionality they provide is breathtaking and a bit overwhelming. Shown in Table 8-1 is a partial list of the technologies supported by XDoclet. Table 8-1. The Different XDoclet Tag Groups Technology/Product Tag Prefixes Description Apache SOAP and Apache Struts @soap Tags for generating SOAP descriptors, @struts Tstruts-config.xml, and validation.xml JSP and servlets @web Tags for generating the web.xml and the @jsp TTLDs for custom JSP tags Enterprise JavaBeans @ejb Tags for generating EJB remote interfaces, home interfaces, and EJB deployment descriptors BEA WebLogic @weblogic Tags used to generate WebLogic-specific deployment descriptor information Borland Enterprise Application Server @bes Tags used to generate Borland Enterprise Application Server–specific deployment descriptor information Oracle Container @oc4j Tags used to generate Oracle for Java (OC4J) Container for Java–specific deployment descriptor information IBM WebSphere @web Tags used to generate WebSphere-specific deployment descriptor information JBoss Application Server @jboss Tags used to generate JBoss-specific deployment descriptor information Macromedia’s JRun @jrun Tags used to generate JRun-specific Application Server deployment descriptor information Resin JSP/Servlet Engine @resin Tags used to generate Resin-specific deployment descriptor information ExoLab’s Castor @castor Tags used to generate O/R Mapping Tool Object/Relational mappings for Castor Hibernate O/R @hibernate Tags used to generate Mapping Tool Object/Relational mappings for Hibernate This list only shows the tag prefixes for each different product or technology set. Each group of products can have literally dozens of XDoclet tags in them. For a full listing of these tags, please visit the XDoclet project site. While there are literally hundreds of XDoclet tags available for use, they all follow the same basic rules and structures. So let’s examine the basic anatomy of an XDoclet tag. CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 297 Ch08_7389_CMP3 9/28/06 8:42 PM Page 297 Anatomy of an XDoclet Tag Three levels of XDoclet tags can be embedded within the source: • Class-level tags •Method-level tags •Field-level tags Class-level tags are placed outside of the actual Java class definition. They provide meta- data about the entire class. In the MemberFilter.java example shown at the beginning of the chapter, the @web.filter tags are class-level tags. Method-level tags are tags used to generate configuration information about individual methods in a class. An example of a method-level XDoclet tag would be @struts.validator. This tag is used to map validation rules from the Validator framework to individual setter methods on an ActionForm class. 4 We will be going through the details of @struts.validator and other @struts tags later on in the chapter. Field-level XDoclet tags are used to provide metadata information about individual prop- erties within Java classes. Frankly, field-level tags are pretty uncommon. We are only aware of one set of XDoclet tags (the @jdo tags) that actually use field-level tags. Although there are three levels of XDoclet tags, the individual XDoclet tags have the same structure. An XDoclet tag will always consist of a tag name followed by one or more tag attrib- utes. Shown in Figure 8-2 is the @web.filter tag taken from the MemberFilter.java class. Figure 8-2. Anatomy of an XDoclet tag In the MemberFilter.java example shown earlier in the chapter, we used only a subset of the @web.filter tags and attributes available. Table 8-2 provides a brief summary of all of the @web.filter tags. CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET298 4. If you are not familiar with the Validator framework, please review Chapter 7. Ch08_7389_CMP3 9/28/06 8:42 PM Page 298 Table 8-2. The @web Tags and Their Descriptions Tag Name Tag Attributes Tag Description @web.filter name: A unique name for the filter. Generates a <filter> This is a mandatory attribute. tag in the web.xml file. display-name: The human-readable display name of the filter. icon: The path and filename of the graphical icon used to represent the filter. description: Description of the filter. @web.filter-init-param name: Name of an initialization Generates an <init-param> parameter used by the filter. tag inside of a <filter> tag. This is a mandatory attribute. value: The value associated with the parameter. description: Description of the initialization parameter. @web.filter-mapping servlet-name: Name of the servlet Generates a <filter-mapping> the web filter is going to be used with. tag with the appropriate url-pattern: URL pattern that the <filter-name> and filter will be used against. <url-pattern> tags. This table only shows the @web tags used for building filter entries in the JavaEdge applica- tion’s web.xml file. There are a number of additional XDoclet tags in the @web tags collection that we have not covered. For full details, please visit the XDoclet site for a complete listing of these tags. Up until this point, we have looked at how to use the @web.filter tags to mark up the MemberFilter.java class. Let’s look at how to actually integrate XDoclet into the JavaEdge application. The integration of Ant and XDoclet, along with the @web tag material we just covered, will lay the foundation for our discussions about the XDoclet @struts tags. Integrating Ant and XDoclet XDoclet currently has seven Ant Tasks that can be used for code generation. Each of these tasks has a number different properties and nested elements available in them, including those listed in Table 8-3. Table 8-3. The Different XDoclet Tag Groups Task Name Task Description <doclet /> The <doclet/> task is the base Ant Task for all of the preceding tasks. It can be used to execute an XDoclet template that is not covered by any of the other tasks. XDoclet allows developers to write their own code- generation templates. For further information on writing your own XDoclet templates, please refer to the XDoclet web site ( http:// xdoclet.sourceforge.net/xdoclet/index.html ). <ejbdoclet /> Used for carrying out various EJB-related tasks, including generating EJB remote interfaces, EJB home interfaces, and EJB deployment descriptors for a wide variety of application servers. Continued CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 299 Ch08_7389_CMP3 9/28/06 8:42 PM Page 299 Table 8-3. Continued Task Name Task Description <hibernatedoclet /> Generates Object/Relational (O/R) mappings for the open source tool Hibernate ( http://www.hibernate.org/). <jdodoclet /> Tasks for generating Java Data Objects (JDO) O/R mappings. JDO is a Sun Microsystems vendor-neutral specification for building a persistence tier. For more information on JDO, please visit http://java.sun.com/products/jdo. <jmxdoclet /> Specifies tasks for generating Java Management Extensions (JMX) classes. JMX is a Sun Microsystems API for building monitoring, instrumenting, and managing Java-based devices, applications, and networks. For more information on JMX, please visit http://java. sun.com/products/JavaManagement/index.html . <mockdoclet /> Generates mock objects for use in testing. Mock objects provide a testing framework that allows developers to test to common Java interfaces. Mock objects allow a developer to simulate the behavior of an object without having to actually fire off an implementation. <webdoclet /> Used for generating a number of web application–related tasks. This Ant Task can generate multiple application-specific web.xml files. In addition, this task is used by the @struts library to generate struts- config.xml and validation.xml files. Obviously, we cannot cover all of the details associated with the tasks listed in Table 8-3. Instead, we will pick one tag, <webdoclet />, and demonstrate how it is used. The <webdoclet /> tag can be used to generate not only an application’s web.xml file, but also a Struts-based application’s struts-config.xml and validation.xml file. Let’s start by writing a simple Ant target called generate-source. The generate-source target will use the <webdoclet /> tag to parse through all of the Java source files in the JavaEdge application and generate a web.xml file based on the @web tags found within the source. Shown here is the generate-source target: <target name="generate-source"> <mkdir dir="${build.generated.dir}"/> <taskdef name="webdoclet" classname="xdoclet.modules.web.WebDocletTask" classpathref="compile.classpath"/> <webdoclet destdir="${build.generated.dir}" mergedir="${src.web.dir}/WEB-INF/mergedir" force="true"> <fileset dir=""${src.java.dir}"> <include name="**/*.java"/> </fileset> <deploymentdescriptor servletspec="2.3" destdir="${build.generated.dir}"> <taglib uri="http://java.sun.com/jstl/ea/core" location="/WEB-INF/c.tld" /> CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET300 Ch08_7389_CMP3 9/28/06 8:42 PM Page 300 </deploymentdescriptor> </webdoclet> </target> The first thing the generate-source target does is create a temporary directory where the generated files are stored. This temporary directory is set in the Ant property build.generated. property. ■Tip The temporary directory that is built by XDoclet is not deleted after each run. If you are using CVS, you will see it note these files every time you run a cvs diff command against your source directory. To avoid this, make sure you include the temporary directory used by XDoclet in the .cvsignore file. This Ant property is defined at the beginning of the JavaEdge build.xml script. Next, you define the <webdoclet > tag using the Ant <taskdef> tag: <taskdef name="webdoclet" classname="xdoclet.modules.web.WebDocletTask" classpathref="compile.classpath"/> The <taskdef> tag just shown defines a new tag, <webdoclet />, that can be used within the generate-src task. The name of the tag is defined by the <taskdef> tag’s name attribute. The classname attribute (in this case xdoclet.modules.web.WebDocletTask) is used to define the fully defined Java class name of the Java class that will be executed when the <webdoclet /> tag is seen within the generate-src task. The <taskdef/> tag’s classpathref defines an Ant reference that holds the classpath for the script. The jar files from the XDoclet distribution must be part of this classpath. ■Note Remember, XDoclet is not part of the Apache Ant distribution. By using the Ant Task <taskdef>, you expose the various XDoclet Java classes that are used to implement an Ant Task to your Ant build scripts. The sample directory in the XDoclet source and binaries distribution contains a build.xml file that demonstrates how to set up not only the <webdoclet /> Ant Task, but also all of the other XDoclet Ant Tasks. The <webdoclet /> task has a number of attributes that must be set in order to use the tag: <webdoclet destdir="${build.generated.dir}" mergedir="${src.web.dir}/WEB-INF/mergedir" force="true"> . . . </webdoclet> CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 301 Ch08_7389_CMP3 9/28/06 8:42 PM Page 301 The first attribute, destdir, tells the <webdoclet /> task where to place all of the files generated. The mergedir attribute is used to tell XDoclet the location of all the merge-point files that hold the static content that needs to be included in the generated web.xml file when the <webdoclet /> task executes. The <webdoclet /> task’s force attribute tells the <webdoclet /> tag to always parse and generate its source and configuration files. Normally, the <webdoclet/> tag will compare the time stamp on the source files against the generated files. If the time stamps are the same and the force attribute is not set or is set to false, the <webdoclet /> task will not generate any files. ■Tip You don’t need to set the force attribute to true, because you can still use the previously generated files. Having this attribute set to true does not hurt for smaller projects, but once the number of files to be processed increases, the time for XDoclet to process them gets unpleasantly long. Set the force attribute to true only when you want to always guarantee you have the latest generated files. A <webdoclet /> task can contain a number of different nested elements. We are only going to examine the nested elements currently shown in the generate-src Ant target. The first nested element is a <fileset/> element: <fileset dir="${src.java.dir}"> <include name="**/*.java"/> </fileset> The <fileset> element tells the <webdoclet /> task where and what source files should be parsed when the <webdoclet /> task is executed. The <fileset/> element used in the generate-src task tells the <webdoclet /> tag to parse all files located in the JavaEdge source directory. The <webdoclet /> tag can generate many different files. If you want the <webdoclet /> tag to generate the web.xml file for an application, you need to embed the <deploymentdescriptor/> element inside of it: <deploymentdescriptor servletspec="2.3" destdir="${build.generated.dir}"> <taglib uri="http://java.sun.com/jstl/ea/core" location="/WEB-INF/c.tld" /> </deploymentdescriptor> The preceding <deploymentdescriptor/> element tells the <webdoclet /> tag to generate a web.xml file that is compliant with the 2.3 version of the servlet specification. The generated web.xml file is placed in the directory defined by the build.generated.dir property. Both the <webdoclet /> and <deploymentdescriptor/> tags have a significant number of additional parameters and nested elements. Please refer to the XDoclet documentation for further details. Using Merge Points As explained earlier, XDoclet is a code generator. However, there are several instances where you need to incorporate static content into the files being generated. This static content is CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET302 Ch08_7389_CMP3 9/28/06 8:42 PM Page 302 located as fragments of text stored inside of various files called merge-point files. The actual names of the individual merge-point files will vary for each different XDoclet task and their corresponding nested elements. For the <webdoclet /> tag, you can have the merge-point files listed in Table 8-4. Table 8-4. The XDoclet Merge-Point Files Filename File Description filter-mappings.xml Contains all non–XDoclet-generated filter mappings filters.xml Contains all non–XDoclet-generated filter definitions listeners.xml Contains all non–XDoclet-generated servlet listener definitions mime-mapping.xml Contains all of the MIME-type mappings for a web.xml file error-page.xml Contains any error page mappings used for the application welcomefiles.xml Contains the welcome file definitions used for the application web-security.xml Contains all non–XDoclet-generated security mappings for the application servlet-mappings.xml Contains all non–XDoclet-generated servlet mappings servlets.xml Contains all non-XDoclet servlet definitions XDoclet and Struts The Struts framework is an extremely powerful tool for building applications. Its use of metadata gives you an unprecedented amount of flexibility in building applications that are modular, easy to change, and more importantly extensible. However, the creation and maintenance of the metadata files needed by a Struts application (that is, the struts-config.xml file, the validation.xml file, etc.) can be a tedious, time-consuming, and error-prone process. The reason for this again ties back to the idea of complexity scalability. The bigger and more complex the application being built around the Struts framework, the more metadata that is needed. This increase in the amount of metadata leads to greater opportunities for con- figuration errors and in turn lost evenings and weekends. Fortunately, the XDoclet tool provides you with a number of XDoclet tags that can be embedded inside of your Struts classes (that is, the Action and ActionForm classes) to simplify the process of generating your Struts configuration files. Over the next several sections in this chapter, we will be looking at how to use the XDoclet Struts tags to perform such common tasks as •Declaring Struts form beans within the struts-config.xml file •Declaring Struts actions within the struts-config.xml file •Declaring application exceptions within the struts-config.xml file •Mapping validation rules from the Validator framework to a Struts Action class •Modifying the <webdoclet /> tag to generate the Struts metadata files CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 303 Ch08_7389_CMP3 9/28/06 8:42 PM Page 303 Declaring Struts Form Beans As you saw in Chapter 3, in order to set up a web form to collect data from an end user, you need to write an ActionForm class to hold the data submitted by the user and then add a <form-bean/> tag to the application’s struts-config.xml file. Once this <form-bean/> entry has been added, it can be used in an <action/> tag’s name attribute. You can automate the creation of the <form-bean/> entry in the struts-config.xml file by using the XDoclet’s @struts-form tag. This tag is a class-level tag and is extremely easy to implement within an ActionForm class. Following is the PostStoryForm.java class using the @struts-form tag: package com.apress.javaedge.struts.story; /** * Standard Struts class that collects data submitted by the end user. * @author jcarnell * * XDoclet Tag * @struts.form name="postStoryForm" * */ public class PostStoryForm extends ActionForm {} In the preceding example, the @struts.form will generate a <form-bean/> in the JavaEdge application’s struts-config.xml file that looks something like this: <form-beans> <form-bean name="postStoryForm" type=➂ "com.apress.javaedge.struts.story.PostStoryForm"/> </form-beans> The name attribute in the preceding <form-bean/> entry corresponds to the name attribute set on the @strut.form XDoclet tag. XDoclet picks up the <form-bean/> tag’s type attribute when the tool is parsing the PostStoryForm.java file. If you have any <form-bean/> tags that are not generated by XDoclet, they can be defined as a merge-point file called struts-forms.xml. The content of this merge-point file will be included immediately following any <form-bean/> tags generated by XDoclet. Now that you have seen how to generate <form-bean/> tags using XDoclet, we will show you how to use the @struts.action tag embedded within your Action classes to generate <action/> tags within the JavaEdge application’s struts-config.xml file. Declaring Struts Actions The XDoclet @struts.action tag can be a bit intimidating when you first encounter it within the XDoclet documentation. Although it does have a large number of attributes, you will find that many of these attributes map to attributes that already have to be defined for a Struts <action/> tag. If you look at the PostStoryAction class shown here, you will see that this is the case: CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET304 Ch08_7389_CMP3 9/28/06 8:42 PM Page 304 /** * @author jcarnell * * Struts Action class used to submit a story by the end user. * * XDoclet Tags * @struts.action path="/postStory" * input="/WEB-INF/jsp/postStory.jsp" * name="postStoryForm" * scope="request" * validate="true" @struts.action-forward name="poststory.success" path="/execute/homePageSetup" *@struts.action-exception *type="com.apress.javaedge.common.ApplicationException" *path="/WEB-INF/jsp/systemError.jsp" * key="error.system" * XDoclet Tags */ public class PostStory extends Action {} To generate an <action/> tag, you need to use two different XDoclet @struts tags: @struts.action and @struts.action-forward. The @struts.action tag generates the <action/> tag and its corresponding attributes. All of the attributes on the @struts.action tag map to the corresponding attributes on the <action/> tag. 5 * @struts.action path="/postStory" * input="/WEB-INF/jsp/postStory.jsp" * name="postStoryForm" * scope="request" * validate="true" In addition to the @struts.action tag just shown, a @struts.action-forward tag is also defined. The @struts.action-forward tag will generate a <forward/> tag inside of the <action/> tag for the class. * @struts.action-forward name="poststory.success" path="/execute/homePageSetup" A class using the @struts.action tag can also have multiple @struts.action-forward tags defining different forwards that the <action/> tag can redirect the user to. Now, when the PostStory.java class is processed by XDoclet, it will generate the following <action/> and <forward/> tag entries: <action path="/postStory" type="com.apress.javaedge.struts.poststory.PostStory" name="postStoryForm" scope="request" CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 305 5. If you need to review the attributes available on the <action/> tag, please refer to Chapter 2. Ch08_7389_CMP3 9/28/06 8:42 PM Page 305 [...]... import import import import import import org .apache. struts. action.ActionError; org .apache. struts. action.ActionErrors; org .apache. struts. action.ActionMapping; org .apache. struts. action.ActionServlet; org .apache. struts. util.MessageResources; org .apache. struts. validator.ValidatorForm; com .apress. javaedge.common.VulgarityFilter; /** * @author John Carnell * @struts. form name="postStoryValidatorForm" */ public... following nested tag elements could be used to generate Struts configuration files: • tells XDoclet to process any @struts tags and generate a struts- config.xml file • tells XDoclet to process any @struts. validation tags and generate a validation.xml file Ch09 _73 89_CMP3 9/ 27/ 06 11:39 AM CHAPTER Page 3 17 9 ■■■ Logging and Debugging F or a web application of... the @struts. validator and @struts. validator-var tag In the interest of space and trees, we are only going to show the markup for the storyTitle attribute package com .apress. javaedge .struts. poststory; import javax.servlet.http.HttpServletRequest; 309 Ch08 _73 89_CMP3 310 9/28/06 8:42 PM Page 310 CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET import import import import import import import org .apache. struts. action.ActionError;... exception that is going to be caught and processed when thrown by the action This is a mandatory field 3 07 Ch08 _73 89_CMP3 308 9/28/06 8:42 PM Page 308 CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET Building struts- config.xml Using At this point, we have examined the majority of the XDoclet @struts tags and how they can be used to mark up the Struts classes Now, let’s modify the generate-src... of the global forwards needed within the Struts application struts- actions.xml Holds any non–XDoclet-generated action definitions that the developer wants to be included in the struts- config.xml file struts- actions.xml Holds any non–XDoclet-generated XDoclet tags struts- data-sources.xml Defines any data sources made available through Struts We do not use the Struts data source capability for... easier to work with and easier to maintain with minimal impact on our application’s performance 3 17 Ch09 _73 89_CMP3 318 9/ 27/ 06 11:39 AM Page 318 CHAPTER 9 ■ LOGGING AND DEBUGGING • Configuring Struts logging: In this section, we draw on information from the previous section to show how you can configure Commons Logging and log4j to capture the Struts log messages to make debugging your Struts applications... Logging with the Apache log4j project, you will probably decide that using JDK 1.4 is quite pointless Commons Logging in Other Applications Before we jump into looking at Commons Logging, we want to show you which other applications use Commons Logging for logging As we already mentioned, Struts uses Commons Logging, as do most other Apache projects However, Commons Logging isn’t just restricted to Apache. .. specifying system properties either directly with a call to System.setProperty() or by specifying them in the simplelog.properties file We prefer to use the simplelog.properties file simply because it allows us to change the settings for our logs without having to touch our code The first set of configuration parameters for SimpleLog, listed here, applies to all logs within the application: • org .apache. commons.logging.simplelog.defaultlog:... can easily change the logging provider without having to change your code Apache log4j Apache log4j is a logging package available from the Apache Logging Services project It differs from Commons Logging in many ways, not least because log4j is intended to be a full logging implementation, whereas Commons Logging is more of an abstraction layer around a logging provider Apache log4j supports many advanced... global-exceptions.xml You can use the @struts. action-exception XDoclet tag to mark up individual Action classes where you want to use the local exception handlers In the XDoclet markup for the PostStory class, you can see this XDoclet tag in use: Ch08 _73 89_CMP3 9/28/06 8:42 PM Page 3 07 CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET * @struts. action-exception * type="com .apress. javaedge.common.ApplicationException" . SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 309 Ch08 _73 89_CMP3 9/28/06 8:42 PM Page 309 import org .apache. struts. action.ActionError; import org .apache. struts. action.ActionErrors; import org .apache. struts. action.ActionMapping; import. caught and processed when thrown by the action. This is a mandatory field. CHAPTER 8 ■ SPEEDING STRUTS DEVELOPMENT WITH XDOCLET 3 07 Ch08 _73 89_CMP3 9/28/06 8:42 PM Page 3 07 Building struts- config.xml. how to use the XDoclet Struts tags to perform such common tasks as •Declaring Struts form beans within the struts- config.xml file •Declaring Struts actions within the struts- config.xml file •Declaring

Ngày đăng: 12/08/2014, 22:22

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan