用Struts实现用户登录

实现用户登录

一、添加框架

      1、添加jar commons-fileupload commons-io javassist commons-lang3 freemarker ognlstruts2-core log4j

      2、配置  web.xml 前端控制器    

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns="http://xmlns.jcp.org/xml/ns/javaee"

    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

    id="WebApp_ID" version="3.1">

    <filter>

       <filter-name>struts2</filter-name>

       <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>struts2</filter-name>

       <url-pattern>/*</url-pattern>

    </filter-mapping>

    <welcome-file-list>

       <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

</web-app>

 

      3、定义struts2的核心配置文件      

创建src/struts.xml文件

struts2-core-2.5.16.jar/ struts-2.5.dtd中复制

<!DOCTYPEstruts PUBLIC

      "-//Apache Software Foundation//DTDStruts Configuration 2.5//EN"

      "http://struts.apache.org/dtds/struts-2.5.dtd">

struts.xml

配置如下:

<?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="aaa" extends="struts-default"></package>

</struts>  

      4部署项目到服务器中,启动服务器,查看控制台报错信息,从而判定框架的准备工作是否完成。

5、定义欢迎首页

 配置web.xml

<welcome-file-list>

       <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

6、定义页面 index

<%@ page language="java" pageEncoding="GBK"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<body>

    <a href="loginput.action">登录系统</a>

</body>

</html>

 

1、 请求loginput.action打开输入页面

问题1Struts2中默认请求控制器的地址后缀为.action或者没有后缀

这是在框架中通过常量定义的  stuts2-core.jar/org/apache/struts2/default.properties

如果修改,可以在sturts.xml中通过常量配置标签进行修改

如果定义多个后缀,中间用逗号隔开,例如dd,bb,cc

2、 定义控制器

a)   Struts2是一个实现了MVC模式的框架

b)   Model:Action(业务控制器),运行特征为多实例单线程的运行方式

c)   View:Struts2默认提供了4种视图技术(jsp xsltvelocity freemarker),同时提供了Result接口允许用户自定义扩展。学习过程中使用的是jsp,建议大家抽额外时间学习freemarker

d)   Controller:前端控制器StrutsPrepareAndExecuteFilter+一组拦截器(当定义的控制器所在包继承struts-defualt时自动引入了一组拦截器)

定义控制器有3种方法:

    方法1:不继承任何类不实现任何接口 ---体现了struts2的轻侵入性

    缺陷:方法名称错误在编译器不能发现

            返回的逻辑地址名没有规则

方法2:引入Action接口

publicinterface Action {

Action接口中定义了5个常量用于规范逻辑地址名;定义了抽象方法用于规范方法签名

    publicstaticfinal String SUCCESS = "success";表示控制器中执行正常,跳转到成功页面

 

    publicstaticfinal String NONE = "none";表示控制器中执行正常,但是不跳转任何页面.一般用于测试

    publicstaticfinal String ERROR = "error";表示控制器中执行中出现严重错误,需要跳转到错误处理页

    publicstaticfinal String INPUT = "input";表示设置对应的输入页面,一般用于输入的报错显示

    publicstaticfinal String LOGIN = "login";设置登录输入页面

 

    public String execute() throws Exception;抽象方法,如果类实现了这个接口则必须实现这个方法。如果方法签名错误则编译报错

}

 

方法3:『推荐使用』struts2为了进一步简化Action的定义方法,提供了一个父类ActionSupport

public class ActionSupport

implements Action, 实现了Action接口,则5大常量和execute方法签名有效

Validateable, ValidationAware,对于服务器端数据校验提供了支持

TextProvider, LocaleProvider,对于国际化I18N、本地化L10N

 Serializable序列化接口

ActionSupport类中提供了execute方法的默认实现,不做任何处理直接跳转到success对应的页面

配置方法:

规则:在<action>中如果不配置class属性时,则默认classActionSupport

如果当一个请求地址不需要进行任何处理时,可以使用上面的规则,避免定义Action

访问loginput.action时直接跳转到login.jsp页面

 

如何在action中接收用户提交数据?

方法1:属性驱动

页面

Action

<input name="username"/>

public class LoginAction extends ActionSupport{

       private String username

}

get/set方法

传递数据的依据为属性名称对应

在页面中的输入项名称username对应action类中的属性username,两个名称一致即可

方法2:模型驱动[推荐使用]

可以将一组数据直接填充到复杂类型的属性中

页面

Action

<input name="username"/>

Public class LoginAction implements ModelDriver<UserBean>{模型驱动,需要实现getModel方法

   Private UserBean user=new UserBean();

}

对应接收数据的值bean,例如UserBean

Public class UserBean{

      private String username;

}

 

提交的username\password等请求参数,会按照参数名称对应值bean属性名称的方式注入到bean属性中.如果提交的请求参数名称没有对应的属性(例如login.action?uname=3333,bean属性中不能接受到参数(也就是说UserBean中没有uname属性)

方法3:对象驱动的方式,这种方式一般不推荐

<input name=”user.username”/>其中user对应的是Action中的UserBean类型的属性user

Public class UserAction{

    Private UserBean user;//使用属性驱动可new也可不new,当前Action类不需要实现ModelDriven接口,对应的user属性上添加get/set方法即可

}

Public class UserBean{

    Private String username;

}

 

个人运用:

import org.apache.commons.lang3.StringUtils;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

import dao.IUserDao;

import entry.UserBean;

import util.DaoFactory;

public class LoginAction extends ActionSupport implements ModelDriven<UserBean> {

    private static final long serialVersionUID = -1085416037846142329L;

    private UserBean user = new UserBean();

    private IUserDao userDao = DaoFactory.getUserDao();

    @Override

    public String execute() throws Exception {

       boolean bb = userDao.login(user);

       if (bb) {

           return SUCCESS;

       } else {

           this.addActionError("登录失败!请重新登录");// 定义action级别的报错信息,在页面中可以使用标签<s:actionError/>进行显示

           return INPUT;

       }

    }

    public void validate() {

    if(user.getUsername()==null||user.getUsername().trim().length()< 1)

           this.addFieldError("username", "同户名不能为空!");

       if (StringUtils.isEmpty(user.getPassword()))

           this.addFieldError("password", "用户口令不能为空!");

    }

    public UserBean getModel() {

       return user;

    }

}

 

问题:提交数据的中文乱码问题?

Struts2中有个运行时常量   struts2-core.jar

/org/apache/struts2/default.properties

定义的是struts2中所采用的默认编码字符集

解决方法1:【推荐】

所有的页面统一使用utf-8编码,提交的信息中最好不包含中文,如果包含中文请使用post的提交方法

<%@ pagelanguage="java" pageEncoding="UTF-8"%>

方法2:如果需要修改编码

则在struts.xml中重新定义常量即可

<constantname=”struts.i18n.encoding”value=”GBK”></constant>

然后所有的页面都是用相同的编码字符集即可,提交的信息中最好不包含中文,如果包含中文请使用post的提交方法

编码实现服务器端数据校验

action类中定义方法validate()可以编码实现服务器端数据校验

public void validate() {

       if (user.getUsername() == null || user.getUsername().trim().length() < 1)

           this.addFieldError("username", "同户名不能为空!");

       if (StringUtils.isEmpty(user.getPassword()))

           this.addFieldError("password", "用户口令不能为空!");

    }

 

addFieldError(username对应的就是输入域的name,用于决定未来的报错显示位置”,”具体的报错提示信息”):用于添加和输入域相关的报错信息

报错:

Validate方法在数据提交的执行流程:

1、 创建action对象  Class.forName(“”).newInstance()

2、 调用set方法注入请求参数

a)   采用的是模型驱动则使用的是getModel().setXXX

3、 调用validate方法,

a)   如果添加了报错信息addFieldError时,则自动转向到input,不会调用execute方法

b)   如果没有添加报错信息,则继续执行execute()方法

报错信息的显示问题?

定义页面时可以不使用Struts2的标签库,但是Struts2为了简化页面也提供了标签库,使用这个标签库可以方便页面的编写

 

<%@page import="java.util.Enumeration"%>

<%@ page language="java" pageEncoding="UTF-8"%>

<%@taglib uri="/struts-tags" prefix="s"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<s:head />

</head>

<body>

    <s:actionerror />

    <s:form action="login.action" method="post">

       <s:textfield name="username" label="用户名称" />

       <s:password name="password" label="用户密码" />

       <tr>

           <td colspan="2"><s:submit value="登录系统" theme="simple" />

            <s:reset value="重置数据" theme="simple" />

           </td> 

       </tr>

    </s:form>

</body>

</html>

 

具体显示中位置出错?

Struts2标签库中提供了4种主题:xhtml(默认主题,采用<table>进行显示控制)   css_xhtml simple ajax

<form id="login" name="login" action="login.action" method="post">

<table class="wwFormTable">

    Username:<tr>

    <td class="tdLabel"></td>

    <td

            class="tdInput"           

><input type="text" name="username" value="" id="login_username"/></td>

</tr>

 

<br/>

    <input type="submit" value="Login"/>

</table></form>

显示效果:

添加一个标签<s:head/>

会使用红色显示报错信息

如果需要人为控制报错显示,可以使用标签<s:fielderror/>

<s:fielderror/>显示所有的输入域相关的报错信息

<s:fielderrorfieldName="username"/>显示和username输入域相关的报错信息

标签的默认主题为xhtml

默认按钮是一行一个按钮,如果需要进行调整,可以在标签中使用theme属性设置所使用的主题

实现用户登录

1、定义欢迎首页

<ahref="loginput.action">登录系统</a>

2、定义配置,使不通过定义控制器类的方式实现跳转页面[不允许直接从页面跳转到页面]  struts.xml

<?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>

   <constant name="struts.action.extension" value="action"/>

   <package name="aaa" extends="struts-default">

       <action name="login" class="action.LoginAction">

          <result>/welcome.jsp</result>

          <result name="input">/login.jsp</result>

       </action>

       <action name="loginput">

          <result name="success">/login.jsp</result>

       </action>

   </package>

</struts>

 

3、 定义页面,可以使用stuts2的标签库简化页面编写

4、定义控制器接受客户端提交数据

4.1、定义接收用户提交数据的值bean

import java.io.Serializable;

public class UserBean implements Serializable {

    private static final long serialVersionUID = -5234379269023696981L;

    private long id;

    private String username;

    private String password;

    public long getId() {

       return id;

    }

    public void setId(long id) {

       this.id = id;

    }

    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;

    }

    @Override

    public String toString() {

       return "UserBean [username=" + username + "]";

    }

 

}

 

4.2、定义控制器

定义服务器端数据校验方法

部署应用并提交空数据进行校验

如果输入了用户名称,但是没有输入用户口令情况

import org.apache.commons.lang3.StringUtils;

 

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

 

import dao.IUserDao;

import entry.UserBean;

import util.DaoFactory;

 

public class LoginAction extends ActionSupport implements ModelDriven<UserBean> {

 

    private static final long serialVersionUID = -1085416037846142329L;

    private UserBean user = new UserBean();

    private IUserDao userDao = DaoFactory.getUserDao();

 

    @Override

    public String execute() throws Exception {

       boolean bb = userDao.login(user);

       if (bb) {

           return SUCCESS;

       } else {

           this.addActionError("登录失败!请重新登录");// 定义action级别的报错信息,在页面中可以使用标签<s:actionError/>进行显示

           return INPUT;

       }

    }

 

    public void validate() {

        if(user.getUsername()==null||user.getUsername().trim().length() < 1)

           this.addFieldError("username", "同户名不能为空!");

       if (StringUtils.isEmpty(user.getPassword()))

           this.addFieldError("password", "用户口令不能为空!");

    }

 

    public UserBean getModel() {

       return user;

    }

}

 

发现<s:form>支持数据回填功能,但是需要知道:密码域永不回填

4.3、定义execute方法实现用户登录的逻辑

使用DAO模式实现usernamepassword的数据库查询

    1个接口  若干实现  1个值bean   1个工厂

接口隔离实现,上层的action调用dao时是通过接口进行调用,不是直接访问实现类

public interface IUserDao {

    public boolean login(UserBean user) throws Exception;

}

定义值bean

定义dao接口的具体实现

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

 

import com.mysql.jdbc.Driver;

 

import entry.UserBean;

 

public class UserDaoImpl implements IUserDao {

    public boolean login(UserBean user) throws Exception {

       boolean res = false;

       Connection conn = null;

       PreparedStatement ps = null;

       ResultSet rs = null;

        try {

           new Driver();

           conn = DriverManager.getConnection("jdbc:mysql:///users?useSSL=false&serverTimezone=UTC", "root", "root");

           ps = conn.prepareStatement("select * from t_users where username=? and password=?");

           ps.setString(1, user.getUsername());

           ps.setString(2, user.getPassword());

           rs = ps.executeQuery();

           if (rs.next()) {

              user.setId(rs.getLong("id"));

              res = true;

           }

       } finally {

           try {

              if (rs != null)

                  rs.close();

           } finally {

              try {

                  if (ps != null)

                     ps.close();

              } finally {

                  if (conn != null)

                     conn.close();

              }

           }

       }

       return res;

    }

}

定义工厂类

public class DaoFactory {

  public static IUserDao getUserDao() {

      return new UserDaoImpl();

  }

}

Action中通过dao接口访问数据库

    Action从功能的角度上说,经常叫做业务控制器,但是不是控制器,是模型,运行特征为多实例单线程

    private UserBean user = new UserBean();

    private IUserDao userDao = DaoFactory.getUserDao();

 

    @Override

    public String execute() throws Exception {

       boolean bb = userDao.login(user);

       if (bb) {

           return SUCCESS;

       } else {

           this.addActionError("登录失败!请重新登录");// 定义action级别的报错信息,在页面中可以使用标签<s:actionError/>进行显示

           return INPUT;

       }

    }

在页面上添加报错显示处理

<s:actionerror/>

定义成功显示页面welcome.jsp

struts.xml中进行配置

<result>/welcome.jsp</result>

定义表结构

cmd  mysql –uroot –p 

Create table if not exists t_users(

    Id bigint primarykey auto_increment,

    Usernamevarchar(20) not null unique,

    Passwordvarchar(20) not null

)engine=innodb default charset utf8;

插入数据:insertinto t_users values(01,”luck”,”123456”);

测试登录

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值