一、工程的基本功能
在login1.jsp输入完用户名与密码,点击登陆按钮便对数据库进行查表操作。
如果密码输入错误,则返回:
如果密码输入正确,则对supername这个字段进行判断,如果是1或者2便跳到registerusrwelcome页面进行进一步的判断看是高权用户还是普通用户。如果是3则跳到管理员页面。
在管理员页面中,存在着一个用户列表的超级链接,点击则对数据库进行查表,把数据库acesys中的整个usr表罗列出来。
二、算法思路
Login1.jsp把文本框的值扔到相应的usrLoginAction.action进行处理(实质上就是一个Java类),如果在struts.xml中判断其返回值,如果是success3则把页面跳转到adminwelcome.jsp,其余的值会有相应的处理。而在adminwelcome.jsp也存在着一个跳转到相应action(实质上也是一个Java类、Java处理文件)进行处理,由于没有到最终处理完毕仅有一种成功的情况(除非程序猿自己写错代码了),因此,无论如何都返回一个的值给struts.xml意思意思,然后自然而然地扔到showAllusr.jsp。至于为什么不直接拉到showAllusr.jsp进行?是因为把数据库操作代码扔到前台实在是太危险鸟!
整个工程的具体文件目录如下所示,已经用不同的颜色标注不同的程序处理线路:
当然,这上面有些页面是无关这个工程的……
三、制作步骤
1.建表
首先在Mysql中配置好一张用户基本信息表usr,如下:
在里面输入好相应的用户信息。表示预先存在着几个用户。当然,注册页面与下面的制作过程同理,只是其中的SQL语句不同罢了。
然后按照之前的方法,用一个已经配置好struts2的WEB-INT替换原工程的WEB-INT。直接配置好struts2,省去编辑的麻烦。
2.写好Login1.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'login1.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<s:property value="error" />
<!--
<form action="usrLoginAction.action" method="post">
用户名:
<input type="text" name="username" />
<br />
密码:
<input type="password" name="password" />
<br />
<input type="submit" value="登陆" />
</form>
-->
<!--
使用struts2的标签实现表单
-->
<s:form action="usrLoginAction" method="post">
<s:textfield name="username" label="用户名"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:submit value="登陆">
</s:submit>
</s:form>
</body>
</html>
这次编写不使用古老的HTML代码。直接使用Struts2标签(也就是Struts2自身的标准去编写)。
首先要在jsp头加入一段使用Struts2标签的声明<%@ taglib uri="/struts-tags" prefix="s"%>
而之后的的编写如上面的代码所示。之前用HTML代码的那一段已经被注释掉,和与Struts2进行对比。
其中<s:property value="error" />的意思是输出Action里面的那个的error变量的值。
同时注意,这里是value而不是values。这是一个名词,表示值等于多少。而不是一个动词,说其值为多少。
3.完成被其它动作继承的com.ascent.po包
(1)在src中先创建好一个被其它动作继承的com.ascent.po包
所谓的包就是一堆文件夹,就是文件夹com下面有个ascent文件夹,然后ascent文件夹里面又放着一个叫po的文件夹。
(2)之后再在po文件创建类就是在po中创建这样那样的java文件。
创建如下所示的dbcon.java,
package com.ascent.po;
import java.sql.*;
public class dbcon {
public static Connection getCon() {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/acesys";
String user = "root";
String password = "root";
con = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
}
因为很多动作都要用到数据库操作,免得写完又写这段代码并且拒绝在其他动作中给这些冗长的链接代码喧宾夺主,于是将这段代码独立出来,之后直接用java继承extends与java引入包import的方式完成。
(3)写好关于传递信息的类usr.java
package com.ascent.po;
public class usr {
protected String username;
protected String password;
protected int id;
protected String email;
protected String tel;
protected String superuser;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getSuperuser() {
return superuser;
}
public void setSuperuser(String superuser) {
this.superuser = superuser;
}
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;
}
}
也就是以后所有在网页中用到的参数都要在这个usr.java被提及。所用的参数都定义为protected,因为要被继承的类所使用。这个java文件没有太大的实质意义,被一堆类似于构造方法的set、get方法充斥,但是这些setter与getter不可或缺。因为在Struts2中,客户端和服务器之间的数据传输全部要用到get、set方法。当在业务逻辑中需要用到页面传过来的值的时候,只要保证Action中属性的set方法和页面中的name属性值<s:textfield name=""/>相同即可。(去掉set,方法名大写变小写),当在显示页面中需要用到业务逻辑中的返回值时,只要保证页面标签的value值<s:property value=""/> 和Action中属性的get方法形同即可。
一开始不知道Struts2是这样要求的,我曾以为这段类似于构造方法的代码过于冗长,便打算偷懒不写,结果发现一是网页无法正常传递参数,二是tomcat报错,很久都找不到原因,后来上网查很久才发现原来如此。
同时,这些getter与setter并不需要自己输入的。在usr.java定义完各种变量之后。如果你是用eclipse,直接按ALT+SHIFT+S之后按R,点完所有你要添加的getter与setter,一点确定便完事。不费时间的^_^。
其实这也间接地体现了Struts2这个框架的系统性与严格性,便于大型企业编程。
4.完成在com.ascent.action动作usrLoginAction.java
上述的准备工作弄完之后,才能正式去弄login1.jsp要求动作的usrLoginAction.java。
package com.ascent.action;
import java.sql.Connection;
import java.sql.ResultSet;
import com.ascent.po.dbcon;
import com.ascent.po.usr;
public class usrLoginAction extends usr {
private Connection con;// 用来续存数据库连接状态的变量
private ResultSet rs;// 用来指向Sql查询结果的游标变量
private String error = "用户名或者密码错误";//这个变量要扔回前台,被前台的标签所查询,同样要有getter与setter
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String execute() {
con = dbcon.getCon();
String sql = "select * from usr where username='" + username
+ "' and password='" + password + "' and delsoft='0'";
try {
rs = con.prepareStatement(sql).executeQuery();// 对con所连接的数据库进行查询,并指向第0项查询结果,请注意第0项是没有东东的,查询结果是从1开始的
if (rs.next()) {// 一开始先下移,指向第一项查询结果,之后就是不停地取值
username = rs.getString("username");
password = rs.getString("password");
superuser = rs.getString("superuser");
}
con.close();//查完数据库记得关。人走带门。
if (superuser.equals("1"))
return "success1";
if (superuser.equals("2"))
return "success2";
if (superuser.equals("3"))
return "success3";
} catch (Exception e) {
return "error";
}
return "error";
}
}
注释上已经也得很明白了,不再多说。
5.编辑struts.xml
在struts.xml加入如下的标签:
<action name="usrLoginAction" class="com.ascent.action.usrLoginAction">
<result name="error">/login1.jsp</result>
<result name="success3">/WEB-INF/adminwelcome.jsp</result>
<result name="success2">/WEB-INF/registusrwelcome.jsp</result>
<result name="success1">/WEB-INF/registusrwelcome.jsp</result>
</action>也是一目了然的。
6.其后就是按照struts.xml的指示完成WEB-INF下的registusrwelcome.jsp与adminwelcome.jsp
(1)registusrwelcome.jsp
同样先在页首加段使用struts2标签的<%@ taglib uri="/struts-tags" prefix="s"%>的声明
之后在<body>标签之间放入一系列的代码,意思很明显,就是判断superuser的值,只要注意struts相关的语法就行。
<s:property value="username" />意为输出action中的username值。找到是哪个用户登陆。
(2)adminwelcome.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'adminwelcome.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
欢迎管理员:
<s:property value="username" />
登陆成功!
<br />
<!--
创建超级链接url1,这条超级链接要跳转的地方为Action findAllusr.java,然后显示名为:用户管理
-->
<s:url id="url1" action="findAllusr"></s:url>
<s:a href="%{url1}">用户管理</s:a>
</body>
</html>
看注释吧,已经一目了然了,不多说了,只要注意struts相关的语法就行。
7.对用户列表的处理
对用户列表的处理,就是如何把所查询的结果,经过不同的传递,并最终显示到页面上。
因为这次需要传递的一个数据集合,而不是单纯的数据,所要会用到ActionContext容器。
前章说到,adminwelcome存在一条需要跳转到动作findAllusr.java处理的超级链接。
findAllusr.java如下:
package com.ascent.action;
import com.ascent.po.*;//首先要继承po下的所有方法与变量。
import com.opensymphony.xwork2.ActionContext;//要使用getContext()把所有数据扔到ActionContext容器里,以便前台调用
import java.sql.*;
import java.util.*;//要使用List
public class findAllusr{
private Connection con;
private ResultSet rs;
public String execute() throws Exception{
List<usr> list=new ArrayList<usr>();//创建一个仅存usr类的List一个
usr u=null;
String sql="select * from usr";
con=dbcon.getCon();
rs=con.prepareStatement(sql).executeQuery();
while(rs.next()){
u=new usr();
u.setId(rs.getInt("id"));
u.setUsername(rs.getString("username"));
u.setEmail(rs.getString("email"));
u.setTel(rs.getString("tel"));
u.setSuperuser(rs.getString("superuser"));
list.add(u);
}
//这个过程之后,这个List相当于[{id1,username1,...},{id2,username2,..},...]
ActionContext.getContext().put("allUsr", list);//之后把这个List压到ActionContext容器里面,并把这个数据集合命名为allUsr
return "go";
}
}
之后在struts.xml添加action:
<action name="findAllusr" class="com.ascent.action.findAllusr">
<result name="go">/WEB-INF/showusr.jsp</result>
</action>
表示所有的处理结果将会扔到showusr.jsp下面处理
showusr.jsp如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%><!--
使用struts标签记得加程序头
--><%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'showusr.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<center>
<h1>
用户列表
</h1><!--
以下是表头静态部分
--><table border="1" width="80%">
<tr>
<td>
ID
</td>
<td>
用户名
</td>
<td>
邮箱
</td>
<td>
电话
</td>
<td>
权限
</td>
<td>
操作
</td>
</tr><!--
意思是创建一个指向数据集合allUsr的游标,然后对里面的东西一个一个地读完,不用定义循环,自动读完所有的东西
s:iterator必须在tr之外,表示创建行,在每一次循环之内。
--><s:iterator value="#request.allUsr">
<tr>
<td>
<s:property value="id" />
</td>
<td>
<s:property value="username" />
</td>
<td>
<s:property value="email" />
</td>
<td>
<s:property value="tel" />
</td>
<td>
<s:if test="superuser==1">普通用户</s:if>
<s:elseif test="superuser==2">高权用户</s:elseif>
<s:elseif test="superuser==3">管理员</s:elseif>
</td>
<td>
操作
</td>
</tr>
</s:iterator>
</table>
</center>
</body>
</html>
struts标签中的iterator是一个从上往下不停往下读取的游标,把它挂在数据集合allUsr上面。
这就是在之前的动作需要用到ActionContext.getContext().put("allUsr", list);的原因。
本文介绍了一个基于Struts2框架的登录系统与用户管理模块的实现过程,包括前端页面设计、数据库交互、后台逻辑处理及Struts2配置。

1689

被折叠的 条评论
为什么被折叠?



