Struts基础应用2——注册

本文介绍将DAO层引入struts,并以注册界面作为例子。内容来自《Java Web轻量级框架项目化教程》
第一篇主要讲了struts的基本原理,由于当时用的是struts1,比较老,这次用struts2,需要重新去官网下包,但struts2基本的思路和1一样,很容易理解。

引入DAO层

可以看到第一篇的数据库操作是在action类里面的,不可复用,于是引入了dao层,定义连接数据库的接口和基本类,然后再dao.impl包里面对接口进行实现(addUser等),这样,在action类里面就可以直接创建一个已经实现的dao.impl类对象,然后直接用addUser进行加用户操作,可以完全忽略数据库那边是怎么处理的。

基本代码

下图中黄色框内为注册功能所需的代码文件。

这里写图片描述

RegisterAction.java 执行业务操作

package com.digital.action;

import com.digital.dao.UserDAO;
import com.digital.dao.impl.UserDAOImpl;
import com.digital.entity.User;
import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport {

    private User user;//给了setter和getter后,对应表单里的name属性值,该Action会自动调用setter方法创建一个实例,里面数据就是表单里的。
    private String repassword;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public String getRepassword() {
        return repassword;
    }
    public void setRepassword(String repassword) {
        this.repassword = repassword;
    }

    public String reg() throws Exception {
        UserDAO ud=new UserDAOImpl();
        int result=ud.addUser(user);
        String back;
        if (result!=0) {
            back="success";
        }else{
            back="input";
        }
        return back;
    }   
}

BaseDAO.java 提供复用性,数据库连接和释放操作。

package com.digital.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class BaseDAO {

    public Connection getConnection(){
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/digital?useSSL=true","root","admin");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    public void closeAll(Connection conn,PreparedStatement pstmt,ResultSet rs){
        if (rs!=null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (pstmt!=null) {
            try {
                pstmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (conn!=null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

UserDAO.java 定义用户操纵数据库的接口,实现由dao.impl里面的类实现。

package com.digital.dao;

import com.digital.entity.User;

public interface UserDAO {
    public int addUser(User user);//添加一个用户
}

UserDAOImpl.java 对UserDAO接口的具体实现。

package com.digital.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.digital.dao.BaseDAO;
import com.digital.dao.UserDAO;
import com.digital.entity.User;

public class UserDAOImpl extends BaseDAO implements UserDAO {

    Connection conn=null;
    PreparedStatement pstmt=null;
    ResultSet rs=null;


    @Override
    public int addUser(User user) {
        int result=0;
        String sql="insert into user_info(userName,password,realName,address,email) values(?,?,?,?,?)";
        try {
            conn=this.getConnection();
            pstmt=conn.prepareStatement(sql);
            pstmt.setString(1, user.getUserName());
            pstmt.setString(2, user.getPassword());
            pstmt.setString(3, user.getRealName());
            pstmt.setString(4, user.getAddress());
            pstmt.setString(5, user.getEmail());
            result=pstmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            closeAll(conn, pstmt, rs);
        }       
        return result;
    }
}

User.java 实体类,属性和setter以及getter方法。

package com.digital.entity;

import java.util.Date;

public class User {
    private int id;
    private String userName;
    private String password;
    private String realName;
    private String sex;
    private String address;
    private String question;
    private String answer;
    private String email;
    private String favorate;
    private int score;
    private Date regDate;

    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;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getRealName() {
        return realName;
    }
    public void setRealName(String realName) {
        this.realName = realName;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getQuestion() {
        return question;
    }
    public void setQuestion(String question) {
        this.question = question;
    }
    public String getAnswer() {
        return answer;
    }
    public void setAnswer(String answer) {
        this.answer = answer;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getFavorate() {
        return favorate;
    }
    public void setFavorate(String favorate) {
        this.favorate = favorate;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public Date getRegDate() {
        return regDate;
    }
    public void setRegDate(Date regDate) {
        this.regDate = regDate;
    }
}

struts.xml
struts2的配置文件和1略有区别。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <package name="digital" namespace="/" extends="struts-default">
        <action name="register" class="com.digital.action.RegisterAction"
                method = "reg"><!--指定方法,否则默认execute-->
            <result name="success">/userinfo.jsp</result>
            <result name="input">/reg.jsp</result>
        </action>
    </package>
</struts>

最后,web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">

   <display-name>digital</display-name>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   <filter>
      <!-- 过滤器名 -->
      <filter-name>struts2</filter-name>
      <!-- 配置Struts 2的核心控制器的实现类 -->
      <filter-class>
         org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
      </filter-class>
   </filter>

<!-- 要拦截的请求 -->
   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

注意点:如果在Action配置中省略了class属性,则代表访问ActionSupport类,其execute方法是直接返回success的。

数据校验 方法一:validate

如果表单有明显的问题(可以不用连接数据库就可以知道错了,如两次密码不一样),那么直接调用action里面的方法,去数据库查一遍显然浪费时间了,Struts2提供了对表单进行验证的方法,我们编写自己的action时只需继承一下,然后改成自己所需要的样子就行了,如在RegisterAction里面添加:

@Override
    public void validate() {
        if(user.getUserName().length()==0)
            addFieldError("username", "用户名不能为空");
        if(user.getPassword().length()==0)
            addFieldError("password", "密码不能为空!");
        if(!(user.getPassword().equals(this.getRepassword())))
            addFieldError("repassword", "确认密码和登录密码不一致!");

        super.validate();
    }

addFieldError后,在reg.jsp中添加:

<font color="red" size="3px"><s:fielderror/></font>

就可以看到类似这样的效果:
这里写图片描述

更多关于error显示的内容可以看看:http://www.cnblogs.com/wangyp/archive/2011/07/13/2104828.html

数据校验 方法二:验证框架

验证的代码用单独的配置文件完成,而不是放在action里面。

RegisterAction-validation.xml,放在和RegisterAction同样的目录下。

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE validators PUBLIC
    "-//Apache Struts//XWork Validator 1.0.3//EN"
    "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
    <field name="user.userName">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="userName.null"></message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="maxLength">10</param>
            <param name="minLength">4</param>
            <message key="userName.length"></message>
        </field-validator>
    </field>

    <field name="user.password">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="password.null"></message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="minLength">4</param>
            <message key="password.length"></message>
        </field-validator>
    </field>

    <field name="repassword">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="repassword.null"></message>
        </field-validator>
        <field-validator type="fieldexpression">
            <param name="expression">user.password==repassword</param>
            <message key="repassword.same"></message>
        </field-validator>
    </field>

    <field name="user.realName">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="realName.null"></message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="maxLength">4</param>
            <param name="minLength">2</param>
            <message>真实姓名长度在${minLength}到${maxLength}之间</message>
        </field-validator>
    </field>

    <field name="user.address">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="address.null"></message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="maxLength">30</param>
            <message>通信地址长度不能超过${maxLength}</message>
        </field-validator>
    </field>

    <field name="user.email">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message key="email.null"></message>
        </field-validator>
        <field-validator type="email">
            <message>电子邮箱格式不符合要求</message>
        </field-validator>
    </field>
</validators>

如果有一些复杂的校验要求,可以用validate方法,拦截器顺序是:先由validation拦截器调用验证框架,再由workflow执行编码验证。
至此,我们知道Struts在处理action的时候,可以通过addFielderror,ActionContext等将“额外信息”保存下来,然后jsp中有特定的方式显示,如

ActionContext ac = ActionContext.getContext();
ac.getSession().put("name","mike");

jsp中:
${sessionScope.name}提取session范围的信息。

这篇博文从源码角度分析了ActionContext类的功能,点击,简单来说就是ActionContext保存了一个Map,里面存放着一些信息,
{message}是按照pageScope,requestScope,sessionScope,applicationScope寻找,直到找到为止。我做了个测试,
1. private变量
只有用${request.message}时才会找到Action类里面的,说明action里面私有变量加的地方默认是request的,而且其他范围(包括applicationScope)都访问不到。
2. actionContext.getApplication().put("CURRENT_USER", usr);往application范围添加数据,但是session也能访问到。

那么,在action里面的private变量是什么时候加到哪里的呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值