WEB项目Struts2练习DEMO
- 用户信息管理 登陆,注册,更新,删除
需求:要求使用Struts2框架实现页面中注册,登陆,更新,删除,要求提供用户设置头像模块,浏览信息时提供头像预览,自由美化页面
实施:
设计数据库:设置用户基本信息,基本账号,密码,以及注册时间,登陆次数,登陆时间,用户个人信息(允许为空)
页面最终效果:功能“加入我们”(注册模块),提交登陆信息
总结:提交登陆信息时连接数据库校验用户信息,如果校验成功保存登陆信息至session,便于下一个页面使用;连接数据库修改当前用户登陆时间,次数等信息
点击加入我们,跳转到注册页面
总结:考虑到合理性,设计成只需要用户密码即可注册成功,用户个人信息可以选择不填,注册成功后跳转至个人信息完善页面,注意各个页面的传值,考虑什么情况下数据可能丢失
总结:发送提交信息请求后,校验信息合法性(判断用户账号是否唯一,使用ajax异步提交验证),保存至数据库
总结:设置头像,提交用户详细信息,加入页面校验(JavaScript)
功能:用户登陆成功时,查询数据库所有用户信息并返回,动态出现分页效果,加入模糊查找功能,将session中的登陆用户反馈给页面,io获取本地服务器中保存的网站总访问量,更新及删除功能关联具体用户
代码总结:
Struts2配置信息
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default" >
<action name="*_*" class="com.ibm.teacherbeta.action.{2}Action" method="{1}">
<result name="loginSuccess">PageLoading.jsp</result>
<result name="loginErr">LoginSaveErr.jsp</result>
<result name="loginError">NameOrPassErr.jsp</result>
<result name="querySuccess">admin/AdministratorPage.jsp</result>
<result name="moveSuccess" type="chain">query_UserInfo</result>
<result name="findSuccess">admin/ModifyUserInfoPage.jsp</result>
<result name="modifySuccess" type="chain">query_UserInfo</result>
<result name="registSuccess">ImproveUserHeaderPage.jsp</result>
<result name="registError">RegistPage2.jsp</result>
<result name="improveSuccess">index2.jsp</result>
</action>
<action name="MFileUpload" class="com.ibm.teacherbeta.action.MFileUploadAction">
<result name="success">index.jsp</result>
</action>
<action name="SFileUpload" class="com.ibm.teacherbeta.action.SFileUploadAction" method="upLoad">
<result name="success">ImproveUserInfoPage.jsp</result>
</action>
</package>
</struts>
头像上传处理的action,上传成功后保存至本地文件中,将本地路径及修改后的图片名称后缀信息保存至数据库
package com.ibm.teacherbeta.action;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.interceptor.RequestAware;
import com.ibm.teacherbeta.biz.UserInfoOperationBiz;
import com.ibm.teacherbeta.util.Application;
import com.opensymphony.xwork2.ActionSupport;
public class SFileUploadAction extends ActionSupport implements RequestAware {
private String account;
private int pageCode;
/**
* serialVersionUID
*/
private static final long serialVersionUID = 3099753924269458155L;
private File doc;//文件内容
private String docContentType;//文件类型
private String docFileName;//文件名
private String dir; //目标目录
private String targetFileName; //目标文件名
Map<String , Object> request ;
public File getDoc() {
return doc;
}
public void setDoc(File doc) {
this.doc = doc;
}
public String getDocContentType() {
return docContentType;
}
public void setDocContentType(String docContentType) {
this.docContentType = docContentType;
}
public String getDocFileName() {
return docFileName;
}
public void setDocFileName(String docFileName) {
this.docFileName = docFileName;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public String getTargetFileName() {
return targetFileName;
}
public void setTargetFileName(String targetFileName) {
this.targetFileName = targetFileName;
}
/**
* @return the account
*/
public String getAccount() {
return account;
}
/**
* @param account the account to set
*/
public void setAccount(String account) {
this.account = account;
}
/**
* @return the pageCode
*/
public int getPageCode() {
return pageCode;
}
/**
* @param pageCode the pageCode to set
*/
public void setPageCode(int pageCode) {
this.pageCode = pageCode;
}
/**
* 上传头像功能模块
*/
public String upLoad() throws Exception {
System.out.println("UserInfoAction.upLoad is .... ");
System.out.println("页面获取到的账户信息:"+account);
String dir = Application.UPLOA_DPATH;
targetFileName = generateFileName(docFileName);
File target = new File(dir,targetFileName);
FileUtils.copyFile(doc, target);
String headerURL = "/upload/"+ targetFileName ;
new UserInfoOperationBiz().improveUserHeader(account, headerURL);
request.put("userImage", headerURL);
request.put("account", account);
return "success";
}
// 产生唯一的文件名
private synchronized String generateFileName(String filename) {
System.out.println("调用更改文件名方法");
int position = filename.lastIndexOf(".");
String ext = filename.substring(position); //png jpg
System.out.println("传入的文件后缀--------------->"+ext);
// return "14test"+ext ;
return account + ext;
}
@Override
public void setRequest(Map<String, Object> request) {
// TODO Auto-generated method stub
this.request = request;
}
}
主页面获取数据库用户信息,以表格的方式呈现,并显示头像信息(jstl标签循环打印所有用户信息,EL表达式取值)
<table id="table_css" style="border: 5px solid #EAEAEA; margin: auto;border-collapse: collapse;">
<tr>
<td style="font-weight: bold;width:90px;">用户头像</td>
<td style="font-weight: bold;width:90px;">用户编号</td>
<td style="font-weight: bold;width:125px;">登陆账号</td>
<td style="font-weight: bold;width:110px;">姓名</td>
<td style="font-weight: bold;width:65px;">性别</td>
<td style="font-weight: bold;width:120px;">生日</td>
<td style="font-weight: bold;width:120px;">爱好</td>
<td style="font-weight: bold;width:120px;">电子邮箱</td>
<td style="font-weight: bold;width:120px;">联系方式</td>
<td style="font-weight: bold;width:120px;">联系地址</td>
<td style="font-weight: bold;width:120px;">注册时间</td>
<td style="font-weight: bold;width:95px;">登陆次数</td>
<td style="font-weight: bold;width:120px;">最后登陆</td>
<td style="font-weight: bold;width:120px;">操作</td>
</tr>
<c:forEach var="user" items="${pageBean.userInfos }">
<tr>
<td><img alt="" src="${user.header }" width="55px" height="55px"></td>
<td>${user.ID }</td>
<td>${user.account }</td>
<td>${user.userName }</td>
<td>${user.sex }</td>
<td>${user.birth }</td>
<td>${user.hobby }</td>
<td>${user.email }</td>
<td>${user.phone }</td>
<td>${user.address }</td>
<td>${user.registTime }</td>
<td>${user.loginCount }</td>
<td>${user.lastLogin }</td>
<td>
<a href="find_UserInfo?account=${user.account }&pass=${user.pass }&pageBean.pageCode=${pageBean.pageCode }" οnclick="return isUpdate()" style="color: #8968CD;font-family: 微软雅黑;">更新</a>
<a href="move_UserInfo?ID=${user.ID }&pageBean.pageCode=${pageBean.pageCode }" οnclick="return isRemove()" style="color: #8968CD;font-family: 微软雅黑;">删除</a>
</td>
</tr>
</c:forEach>
</table>
jstl标签库抬头信息
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
实现主页分页效果,封装分页对象成javabean,使其称为对象,分页对象中包含页码细节信息及该页所有用户信息
package com.ibm.teacherbeta.vo;
import java.util.ArrayList;
import java.util.List;
/**
* 分页查询的实体类
* @author SUMMER
*/
public class PageBean {
/**
* 当前页码
*/
private int pageCode ;
/**
* 每页大小
*/
private int pageSize ;
/**
* 总页数
*/
private int allPages ;
/**
* 共检索出的条数
*/
private int allCount ;
/**
* 保存页面每条数据的集合
*/
private List<UserInfo>userInfos = new ArrayList<UserInfo>();
/**
* @return the pageCode
*/
public int getPageCode() {
return pageCode;
}
/**
* @param pageCode the pageCode to set
*/
public void setPageCode(int pageCode) {
this.pageCode = pageCode;
}
/**
* @return the pageSize
*/
public int getPageSize() {
return pageSize;
}
/**
* @param pageSize the pageSize to set
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
* @return the allPages
*/
public int getAllPages() {
return (allCount-1)/pageSize+1;
}
/**
* @param allPages the allPages to set
*/
public void setAllPages(int allPages) {
this.allPages = allPages;
}
/**
* @return the allCount
*/
public int getAllCount() {
return allCount;
}
/**
* @param allCount the allCount to set
*/
public void setAllCount(int allCount) {
this.allCount = allCount;
}
/**
* @return the userInfos
*/
public List<UserInfo> getUserInfos() {
return userInfos;
}
/**
* @param userInfos the userInfos to set
*/
public void setUserInfos(List<UserInfo> userInfos) {
this.userInfos = userInfos;
}
}
业务实现层(持久层,DAO层)分页的实现,返回PageBean的对象,对象中包含用户信息list,分页功能整合模糊查询功能
/**
* 分页查询
*/
@Override
public PageBean searchByPage(int pageCode, int pageSize, String condition) {
// TODO Auto-generated method stub
PageBean page = new PageBean();
UserInfo userInfo = null;
Connection connection = DBManager.getConnection();
PreparedStatement prepared = null ;
ResultSet resultSet = null ;
String sql = "select count(*) from userinfo";
try {
if (condition != null) {
sql += " where userName like ?";
prepared = DBLink.getPrepare(connection, sql);
prepared.setString(1, "%" + condition + "%");
} else {
prepared = DBLink.getPrepare(connection, sql);
}
resultSet = prepared.executeQuery();
while (resultSet.next()) {
page.setAllCount(resultSet.getInt(1));
}
page.setPageSize(pageSize);
page.setPageCode(pageCode);
if (pageCode > page.getAllPages()) {
pageCode = page.getAllPages();
}
if (condition != null) {
sql = "select * from userinfo where userName like ? limit ?,?" ;
prepared = DBLink.getPrepare(connection, sql);
prepared.setString(1, "%" + condition + "%");
prepared.setInt(2, (pageCode-1)*pageSize);
prepared.setInt(3, pageSize);
} else {
sql = "select * from userinfo limit ?,?";
prepared = DBLink.getPrepare(connection, sql);
prepared.setInt(1, (pageCode-1)*pageSize);
prepared.setInt(2, pageSize);
}
resultSet = prepared.executeQuery();
while (resultSet.next()) {
int ID = resultSet.getInt("id");
String account = resultSet.getString("account");
String pass = resultSet.getString("pass");
String registTime = resultSet.getString("registTime");
int loginCount = resultSet.getInt("loginCount");
String lastLogin = resultSet.getString("lastLogin");
String userName = resultSet.getString("userName");
String sex = resultSet.getString("sex");
String birth = resultSet.getString("birth");
String hobby = resultSet.getString("hobby");
String email = resultSet.getString("email");
String phone = resultSet.getString("phone");
String address = resultSet.getString("address");
String header = resultSet.getString("header");
userInfo = new UserInfo(ID, account, pass, registTime, loginCount, lastLogin, userName, sex, birth, hobby, email, phone, address,header);
page.getUserInfos().add(userInfo);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DBLink.close(connection, prepared);
}
return page;
}
DBCP数据库连接池的实现,DBCP配置信息(properties文件)
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/teacherbeta
username=root
password=1111
maxTotal=100
maxIdle=30
maxWaitMillis=10000
removeAbandonedOnMaintenance=true
removeAbandonedTimeout=180
package com.ibm.teacherbeta.util;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
public class DBManager {
private static DataSource dataSource;
static{
try {
Properties prop = new Properties();
prop.load(DBManager.class.getClassLoader().getResourceAsStream("dbcp.properties"));
dataSource = BasicDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
}
封装数据库常用对象
package com.ibm.teacherbeta.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* 加载驱动,连接数据库,关闭数据库的类
* @author SUMMER
*/
public class DBLink {
/**
* 取得PreparedStatement预处理操作对象
* @param connection 数据库连接对象
* @param sql 执行sql语句
* @return PreparedStatement
*/
public static PreparedStatement getPrepare(Connection connection , String sql) {
PreparedStatement prepared = null ;
try {
prepared = connection.prepareStatement(sql);//取得PreparedStatement对象
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return prepared ;//返回PreparedStatement对象
}
/**
* 关闭数据库连接
* @param connection 数据库连接对象
* @param prepared MySQL预处理操作对象
*/
public static void close(Connection connection , PreparedStatement prepared) {
try {
prepared.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
代码结构