zoukankan      html  css  js  c++  java
  • Struts2 基本配置

    Struts2是一个优秀的MVC框架,也是我比较喜欢用的框架。它个各种配置基本都可以集中在一个xml文档中完成。现在让我们看看如何简单几步实现常用功能。

    一、搭建Struts2的开发环境

    1)首先是利用Maven导入依赖,其实真正使用的只有一个struts2-core包

    <dependencies>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.24</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>            
    pom.xml

    2)新建各种package(其实建包这类的事情都是个人习惯,你也可以等用到再建)

    3)配置web.xml

    顺带提一句,如果你没有通过Maven来引入依赖而是通过Struts官网下载的完整开发包,可以直接找到事例配置文件。直接导入进你的项目就可以了,省时又省力,安全又方便。

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
        <display-name>Struts2 Demo</display-name>
        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    </web-app>
    web.xml

    4)增加资源文件struts.xml(这个文件的默认路径就是在classes下面)

    直接在官方开发包里找一个放进项目中就可以了。

    以上4步就可以完成struts2的开发环境搭建,真的很简单。

    二、功能实现与代码示例

    1)首先是建立测试使用的jsp页面。

    首页:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Basic Struts 2 Application - Welcome</title>
    </head>
    <body>
        <h1>Welcome To Struts 2!</h1>
        <p>
            <a href="register.jsp">Please register</a> for our network station.
        </p>
        <p>
            Here is <a href="login.jsp">login link</a>.
        </p>
    </body>
    </html>
    index.jsp

    跳转成功和跳转失败页面(每次开发我都习惯配置这样一对页面):

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
        <h1>success!</h1>
        <p>Log in to the <a href="manager/management">Management</a></p>
        <s:property value="#session.user" />
        <s:debug></s:debug>
    </body>
    </html>
    success.jsp
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
        <h1>error!</h1>
        <s:property value="#request.message" />
        <s:debug></s:debug>
    </body>
    </html>
    error.jsp

    注册页面:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>register</title>
    </head>
    <body>
        <h1>register</h1>
        <s:form action="register">
            <s:textfield name="userVo.userName" label="User Name" />
            <s:password name="userVo.userPassword" label="User Password" />
            <s:password name="userVo.userPasswordConfirm" label="Confirm" />
            <s:submit />
        </s:form>
    </body>
    </html>
    register.jsp

    登录页面:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>login</title>
    </head>
    <body>
        <h1>login</h1>
        <s:form action="login">
            <s:textfield name="user.userName" label="User Name" />
            <s:password name="user.userPassword" label="User Password" />
            <s:submit />
        </s:form>
    </body>
    </html>
    login.jsp

    后台管理页面:

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <%@ taglib prefix="s" uri="/struts-tags"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <base href="<%=basePath%>">
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>management</title>
    </head>
    <body>
        <h1>Management</h1>
        <a href="manager/management-add">add</a>
        <br />
        <a href="manager/management-remove">remove</a>
        <br />
        <a href="manager/management-modify">modify</a>
        <br />
        <s:property value="#request.operate" />
    </body>
    </html>
    management.jsp

    2)配置struts.xml

    由于我已经事先在IDE中完成了整个项目,所以这里就直接提供完整配置。实际开发中往往都是一条一条增加的,特别是拦截器和监听器的配置其实是在整个action都完成以后才添加的功能,具体的测试步骤就不一一赘述了。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
        <!-- struts2 支持"!"的动态方法调用,但并不建议 -->
        <constant name="struts.enable.DynamicMethodInvocation" value="false" />
        <constant name="struts.devMode" value="true" />
        <!-- 配置一个监听器 -->
        <bean type="com.opensymphony.xwork2.ActionEventListener" class="action.listener.ServiceListener" />
        
        <package name="default" namespace="/" extends="struts-default">
            <!-- 自定义拦截器需要同时继承默认拦截器栈 -->
            <interceptors>
                <interceptor name="timer" class="action.interceptor.Timer" />
                <interceptor-stack name="myStack">
                    <interceptor-ref name="defaultStack" />
                    <interceptor-ref name="timer" />
                </interceptor-stack>
            </interceptors>
            <!-- 在package下配置的拦截器可以对所有action生效 -->
            <default-interceptor-ref name="myStack" />
            <!-- 若用户请求不存在,跳转掉首页。减少报错的几率 -->
            <default-action-ref name="index" />
            <!-- 配置统一的跳转页面,一般针对异常处理 -->
            <global-results>
                <result name="error">/error.jsp</result>
            </global-results>
            <action name="index">
                <result>/index.jsp</result>
            </action>
            <action name="register" class="action.RegisterAction" method="execute">
                <result name="success">/login.jsp</result>
                <result name="input">/register.jsp</result>
            </action>
            <action name="login" class="action.LoginAction" method="login">
                <result name="success">/success.jsp</result>
            </action>
            <!-- 省略了方法调用和结果集返回字符串,默认就是execute()方法和success结果集 -->
            <action name="management" class="action.ManagementAction">
                <result>/management.jsp</result>
            </action>
        </package>
        <!-- 配置包继承 -->
        <package name="manager" namespace="/manager" extends="default">
            <action name="management" class="action.ManagementAction">
                <result>/management.jsp</result>
            </action>
            <!-- 使用通配符的动态方法调用是struts2推荐的方法 -->
            <action name="management-*" class="action.ManagementAction" method="{1}">
                <result name="success">/management.jsp</result>
            </action>
        </package>
    </struts>
    struts.xml

    3)编写功能代码

    (1)model和modelVo

    package model;
    
    public class User {
        private int id;
        private String userName;
        private String userPassword;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserPassword() {
            return userPassword;
        }
    
        public void setUserPassword(String userPassword) {
            this.userPassword = userPassword;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "User [userName=" + userName + ", userPassword=" + userPassword + "]";
        }
    
    }
    User.java
    package model.vo;
    
    public class UserVo {
        private String userName;
        private String userPassword;
        private String userPasswordConfirm;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserPassword() {
            return userPassword;
        }
    
        public void setUserPassword(String userPassword) {
            this.userPassword = userPassword;
        }
    
        public String getUserPasswordConfirm() {
            return userPasswordConfirm;
        }
    
        public void setUserPasswordConfirm(String userPasswordConfirm) {
            this.userPasswordConfirm = userPasswordConfirm;
        }
    
    }
    UserVo.java

    (2)service

    配置了两个用户可以正常登陆,其中admin是管理员可以登陆后台

    package service;
    
    import model.*;
    
    /*
     * 模拟后台数据库操作,orm框架都可以通过这个端口扩展
     */
    public class GeneralService {
        public boolean save(User user) {
            return true;
        }
    
        public boolean login(User user) {
            if (user.getUserName().equals("admin") && user.getUserPassword().equals("admin")) {
                return true;
            }
            if (user.getUserName().equals("Learnhow") && user.getUserPassword().equals("Learnhow")) {
                return true;
            }
            return false;
        }
    
        public boolean isAdmin(User user) {
            if (user.getUserName().equals("admin") && user.getUserPassword().equals("admin")) {
                return true;
            }
            return false;
        }
    }
    GeneralService.java

    (3)action、interceptor和listener

    package action;
    
    import java.util.Map;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    import model.User;
    import service.GeneralService;
    /*
     * 用户登录
     */
    public class LoginAction extends ActionSupport {
        private static final long serialVersionUID = 1L;
        private GeneralService generalService = new GeneralService();
        private User user;
    
        public String login() throws Exception {
            if (generalService.login(user)) {
                //获得session对象,也可以通过SessionAware继承。还可以获得request和application对象。
                Map<String, Object> session = (Map) ActionContext.getContext().get("session");
                session.put("user", user);
                return SUCCESS;
            }
            Map<String, Object> request = (Map) ActionContext.getContext().get("request");
            request.put("message", "The user name or password mistake, please login again");
            return ERROR;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
    }
    LoginAction.java
    package action;
    
    import java.util.Map;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    import model.User;
    import service.GeneralService;
    
    /*
     * 管理员登录
     */
    public class ManagementAction extends ActionSupport {
        // GeneralService对象没有新建,而是通过监听器注入的
        private GeneralService generalService;
        private Map<String, Object> request = (Map) ActionContext.getContext().get("request");
    
        @Override
        public String execute() throws Exception {
            Map<String, Object> session = (Map) ActionContext.getContext().get("session");
            User user = (User) session.get("user");
            if (user.getUserName().equals("admin") && user.getUserPassword().equals("admin")) {
                return SUCCESS;
            }
            return ERROR;
        }
    
        // 动态的add()方法调用
        public String add() throws Exception {
            request.put("operate", "add");
            return SUCCESS;
        }
    
        public String remove() throws Exception {
            request.put("operate", "remove");
            return SUCCESS;
        }
    
        public String modify() throws Exception {
            request.put("operate", "modify");
            return SUCCESS;
        }
    
        public GeneralService getGeneralService() {
            return generalService;
        }
    
        public void setGeneralService(GeneralService generalService) {
            this.generalService = generalService;
        }
    
    }
    ManagementAction.java
    package action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import model.User;
    import model.vo.UserVo;
    import service.GeneralService;
    /*
     * 用户注册
     */
    public class RegisterAction extends ActionSupport {
        private static final long serialVersionUID = 1L;
        private GeneralService generalService = new GeneralService();
        private User user;
        //添加了setter和getter方法的变量会跟随请求被存入值栈
        private UserVo userVo;
    
        @Override
        public String execute() throws Exception {
            user = new User();
            user.setUserName(userVo.getUserName());
            user.setUserPassword(userVo.getUserPassword());
            generalService.save(user);
            return SUCCESS;
        }
        
        //struts2的验证方法,可以针对表单做动态验证。调用验证方法的返回字符串是input
        @Override
        public void validate() {
            if (userVo.getUserName().length() == 0) {
                addFieldError("userVo.userName", "user name is required.");
            }
            if (userVo.getUserPassword().length() == 0) {
                addFieldError("userVo.userPassword", "user password is required.");
            }
            if (!userVo.getUserPassword().equals(userVo.getUserPasswordConfirm())) {
                addFieldError("userVo.userPasswordConfirm", "passwords don't match");
            }
        }
    
        public UserVo getUserVo() {
            return userVo;
        }
    
        public void setUserVo(UserVo userVo) {
            this.userVo = userVo;
        }
    }
    RegisterAction.java
    package action.interceptor;
    
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    
    /*
     * 给action添加一个运行时间的拦截器
     */
    public class Timer extends AbstractInterceptor {
    
        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
            long startTime = System.currentTimeMillis();
            String result = invocation.invoke();
            long endTime = System.currentTimeMillis();
            System.out.println("Time:" + (endTime - startTime));
            return result;
        }
    
    }
    Timer.java
    package action.listener;
    
    import com.opensymphony.xwork2.ActionEventListener;
    import com.opensymphony.xwork2.util.ValueStack;
    
    import action.*;
    import model.*;
    import service.GeneralService;
    /*
     * 实现的ActionEventListener的监听器,可以针对action和异常处理
     * 根据官方文档的描述,监听器的作用是在action实例化的过程中或有异常发生的时候增加逻辑处理,这一点不同于拦截器。也就是说监听器是可以对action做出区分的。
     */
    public class ServiceListener implements ActionEventListener {
    
        public Object prepare(Object action, ValueStack stack) {
            if (action instanceof ManagementAction) {
                //通过struts2框架为特定action注入对象
                ((ManagementAction) action).setGeneralService(new GeneralService());
            }
            return action;
        }
    
        public String handleException(Throwable t, ValueStack stack) {
            return null;
        }
    
    }
    ServiceListener.java

    Struts2基本配置大概就是这样,其实也没有什么难度,关键是好用。不过现在好像依然使用Struts2新开发的项目越来越少了,更多项目使用SpringMVC代替,但是如果是我自己写项目Struts依然是首选,因为我比较“土”!

    最后依照惯例附上整个项目的部署目录和IDE版本:

  • 相关阅读:
    python
    redis
    mongodb replica on aws ec2
    mysql
    java正则表达式
    终端make命令和Git学习
    linux和shell学习
    centos普通用户安装jenkins
    centos7普通用户安装jdk
    WPF动画
  • 原文地址:https://www.cnblogs.com/learnhow/p/5112794.html
Copyright © 2011-2022 走看看