配置ssh框架,struts2 2.3.24 、hibernate5x 、spring 4.2.4
第一步 :导入jar包
antlr-2.7.7.jar --------检查、识别Hibernate中用到的hql语句
aopalliance-1.0.jar --------这个包是AOP的API包,Spring用的
asm-3.3.jar --------Struts2使用,ASM字节码库
asm-commons-3.3.jar --------Struts2
asm-tree-3.3.jar --------Struts2
aspectjweaver-1.8.7.jar --------aspectj框架支持的包
c3p0-0.9.2.1.jar --------数据库连接池spring配置里面用
commons-beanutils-1.8.3.jar
commons-fileupload-1.3.1.jar
commons-io-2.2.jar --------针对java.io.InputStream和Reader进行了扩展
commons-lang3-3.2.jar ---------对java.lang.*的扩展
commons-logging-1.2.jar
dom4j-1.6.1.jar --------读写XML文件
freemarker-2.3.22.jar --------解决Struts2当中缺少freemarker.jar问题
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-c3p0-5.0.7.Final.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
junit-4.9.jar --------单元测试
log4j-1.2.16.jar --------日志
mchange-commons-java-0.2.3.4.jar
mysql-connector-java-5.1.7-bin.jar --------这里我使用mysql数据库所以导包
ognl-3.0.6.jar --------struts的ognl
slf4j-api-1.6.1.jar --------日志管理
slf4j-log4j12-1.7.2.jar
spring-aop-4.2.4.RELEASE.jar
spring-aspects-4.2.4.RELEASE.jar
spring-beans-4.2.4.RELEASE.jar
spring-context-4.2.4.RELEASE.jar
spring-core-4.2.4.RELEASE.jar
spring-expression-4.2.4.RELEASE.jar
spring-jdbc-4.2.4.RELEASE.jar
spring-orm-4.2.4.RELEASE.jar
spring-test-4.2.4.RELEASE.jar
spring-tx-4.2.4.RELEASE.jar
spring-web-4.2.4.RELEASE.jar
struts2-convention-plugin-2.3.24.jar
struts2-core-2.3.24.jar --------struts核心
struts2-spring-plugin-2.3.24.jar
xwork-core-2.3.24.jar --------struts 2.3未整合,2.5后整合在struts-core的jar包中
第二步:逐个配置框架,先struts、再hibernate,再spring,再整合
-
struts2
src下创建struts.xml文件,引入约束dtd
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- ...... -->
</struts>
web.xml中配置过滤器
<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>
- hibernate
hibernate核心配置文件整合到spring中,实体类配置文件正常写
创建实体类,这里我创建User(登录用户)
private Integer uid;
private String username;
private String password;
private String address;
//生成get,set方法
配置User.hbm.xml,这里数据库表会自动创建
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 1 配置类和表对应
class标签
name属性:实体类全路径
table属性:数据库表名称
-->
<class name="cn.itssh.entity.User" table="t_user">
<id name="uid" column="uid">
<generator class="native"></generator>
</id>
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="address" column="address"></property>
</class>
</hibernate-mapping>
- spring
建立bean.xml文件,引入schema约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
在bean配置文件中,配置数据库,c3p0连接池
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/logindemo"></property>
<property name="user" value="root"></property><!-- 你的数据库用户名 -->
<property name="password" value="root"></property><!-- 你的数据库密码 -->
</bean>
在bean中配置hibernate,并引入hibernate映射文件
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!--注入dataSource -->
<property name="dataSource" ref="dataSource"></property>
<!-- hibernate配置文件<key,value>。。 -->
<property name="hibernateProperties" >
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<!-- hibernate映射文件:数组。。 -->
<property name="mappingResources">
<list>
<value>User.hbm.xml路径</value>
</list>
</property>
</bean>
web.xml配置context-param
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
第三步: 创建UserAction类,来实现User(登录用户)的功能
继承ActionSupport,实现ModelDriven接口(用模型驱动接收数据方便)
public class UserAction extends ActionSupport implements ModelDriven<User> {
private User user;
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
public String login(){
return "login";
}
}
先不实现登录,先去配置struts
<package name="demo" extends="struts-default" namespace="/">
<action name="user_*" class="cn.itssh.action.UserAction" method="{1}">
<result name="loginsuccess">/success.jsp</result>
<result name="login">/login.jsp</result>
</action>
</package>
第四步:去搞ui,那个登录jsp和登陆成功的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
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>
<title>登录</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="css/bootstrap.min.css"/>
<link href="css/signin.css" rel="stylesheet">
<script src="js/jquery-3.3.1.min.js"></script>
<script src="js/bootstrap.js"></script>
</head>
<body class="text-center">
<div id="loginDiv">
<form class="form-signin form-horizontal" action="${pageContext.request.contextPath}/user_login.action" onsubmit="return validate();" method="post">
<div id="box1" class="row row-margin-bottom form-group">
<label>用 户 名:</label>
<input id="username" class="form-control" type="text" name="username" placeholder="请输入用户名..." required oninvalid="setCustomValidity('请输入您的用户名');" oninput="setCustomValidity('');"/>
</div>
<div id="box2" class="row row-margin-bottom form-group">
<label>密 码:</label>
<input id="password" name="password" type="text" class="form-control" placeholder="请输入密码..." required oninvalid="setCustomValidity('请输入您的密码');" oninput="setCustomValidity('');"/>
</div>
<div id="box3" class="row row-margin-bottom form-group">
<label>图型验证码:</label>
<input type="tel" class="form-control" placeholder="请输入图形验证码..." id="input1" />
</div>
<div class="row row-margin-bottom form-group">
<span>
<canvas id="canvas" width="120" height="45"></canvas>
<a href="#" id="changeImg">看不清,换一张</a>
</span>
</div>
<div class="row row-margin-bottom" >
<button type="submit" class="btn btn-primary" >确 认</button>
<button type="button" id="register_button" class="btn btn-primary">注 册</button>
</div>
</form>
</div>
<div id="registerDiv" style="display: none;">
<form class="form-signin form-horizontal" action="${pageContext.request.contextPath}/user_register.action" method="post">
<div id="box4" class="row row-margin-bottom form-group">
<label>用户名:</label>
<input id="new_username" class="form-control" type="text" name="username" placeholder="请输入用户名..." required oninvalid="setCustomValidity('请输入您的用户名');" oninput="setCustomValidity('');"
aria-describedby="inputSuccess2Status" onblur="registerCheck()" onfocus="remove()"
/>
</div>
<p id="msg_user" style="margin-left: 150px"></p>
<div id="box5" class="row row-margin-bottom form-group">
<label>密 码:</label>
<input id="ipwd" name="password" type="text" class="form-control" placeholder="请输入密码..." required oninvalid="setCustomValidity('请输入您的密码');" oninput="setCustomValidity('');"/>
</div>
<div id="box6" class="row row-margin-bottom form-group">
<label>确认密码:</label>
<input id="i2pwd" type="text" class="form-control" placeholder="请再次输入密码..." required oninvalid="setCustomValidity('请再次输入您的密码');" oninput="setCustomValidity('');"d"/>
</div>
<p id="msg_pwd" style="margin-left: 150px"></p>
<div id="box7" class="row row-margin-bottom form-group">
<label>地 址:</label>
<input id="new_address" name="address"type="text" class="form-control" placeholder="请输入地址..." required oninvalid="setCustomValidity('请输入您的地址');" oninput="setCustomValidity('');"/>
</div>
<div class="col-sm-offset-2 col-sm-10">
已有账号?点击<a href="login.jsp">登录!</a>
<button id="btn_register" type="submit" class="btn btn-success" style="float: right" >注 册</button>
</div>
</form>
</div>
<br/>
<p class="mt-5 mb-3 text-muted">© Designed By whd</p>
<script type="text/javascript">
/* 用户重复检查 */
function registerCheck() {
http_request = new XMLHttpRequest();
var url = "check_registerCheck?username=" + $("#new_username").val();
http_request.onreadystatechange = function () {
if (http_request.readyState == 4 && http_request.status == 200) {
var s = http_request.responseText;
if (s == "true") {
$("#box4").addClass("has-error");
$("#msg_user").html("<font color='red'>用户名重复</font>");
$("#btn_register").attr("disabled",true);
}else{
$("#msg_user").html("<font color='green'>用户名可以使用</font>");
$("#btn_register").attr("disabled",false);
}
}
}
http_request.open("POST", url, true);
http_request.send();
}
function remove() {
$("#box4").removeClass("has-error");
}
</script>
<script type="text/javascript">
/** 密码判断 ,取自:https://blog.csdn.net/m0_38139268/article/details/81903895 **/
$(document).ready(function(){
$('#ipwd').on('input propertychange', function() {
//input propertychange即实时监控键盘输入包括粘贴
var pwd = $.trim($(this).val());
//获取this,即ipwd的val()值,trim函数的作用是去除空格
var rpwd = $.trim($("#i2pwd").val());
if(rpwd!=""){
if(pwd==""&&rpwd==""){
//若都为空,则提示密码不能为空,为了用户体验(在界面上用required同时做了处理)
$("#msg_pwd").html("<font color='red'>密码不能为空</font>");
}
else{
if(pwd==rpwd){ //相同则提示密码匹配
$("#msg_pwd").html("<font color='green'>两次密码匹配通过</font>");
$("#btn_register").attr("disabled",false); //使按钮无法点击
}else{ //不相同则提示密码匹配
$("#msg_pwd").html("<font color='red'>两次密码不匹配</font>");
$("#btn_register").attr("disabled",true);
}
}}
})
})
//由于是两个输入框,所以进行两个输入框的几乎相同的判断
$(document).ready(function(){
$('#i2pwd').on('input propertychange', function() {
var pwd = $.trim($(this).val());
var rpwd = $.trim($("#ipwd").val());
if(pwd==""&&rpwd==""){
$("#msg_pwd").html("<font color='red'>密码不能为空</font>");
}
else{
if(pwd==rpwd){
$("#msg_pwd").html("<font color='green'>两次密码匹配通过</font>");
$("#btn_register").attr("disabled",false);
}else{
$("#msg_pwd").html("<font color='red'>两次密码不匹配</font>");
$("#btn_register").attr("disabled",true);
}
}
})
})
</script>
<script type="text/javascript">
/**注册div的显示与隐藏 **/
document.getElementById("register_button").onclick=function(){
document.getElementById("registerDiv").style.display="block" ;
document.getElementById("loginDiv").style.display="none" ;
}
document.getElementById("returnlogin_button").onclick=function(){
document.getElementById("registerDiv").style.display="none" ;
document.getElementById("loginDiv").style.display="block" ;
}
</script>
<script>
/**
验证码生成和判断js版
**/
/**生成一个随机数**/
var str; //全局的str
function validate() {
var inputCode = document.getElementById("input1").value;
if (inputCode.length <= 0) {
alert("请输入验证码!");
return false;
} else if (inputCode != str) {
alert("验证码输入错误!"+code);
document.getElementById("input1").value = "";
return false;
createCode();//刷新验证码
} else {
return true;
}
}
function randomNum(min,max){
return Math.floor( Math.random()*(max-min)+min);
}
/**生成一个随机色**/
function randomColor(min,max){
var r = randomNum(min,max);
var g = randomNum(min,max);
var b = randomNum(min,max);
return "rgb("+r+","+g+","+b+")";
}
drawPic();
document.getElementById("changeImg").onclick = function(e){
e.preventDefault();
drawPic();
}
/**绘制验证码图片**/
function drawPic(){
var canvas=document.getElementById("canvas");
var width=canvas.width;
var height=canvas.height;
var ctx = canvas.getContext('2d');
ctx.textBaseline = 'bottom';
/**绘制背景色**/
ctx.fillStyle = randomColor(180,240); //颜色若太深可能导致看不清
ctx.fillRect(0,0,width,height);
/**绘制文字**/
str = 'ABCEFGHJKLMNPQRSTWXY123456789';//str在此
for(var i=0; i<4; i++){
var txt = str[randomNum(0,str.length)];
ctx.fillStyle = randomColor(50,160); //随机生成字体颜色
ctx.font = randomNum(15,40)+'px SimHei'; //随机生成字体大小
var x = 10+i*25;
var y = randomNum(25,45);
var deg = randomNum(-45, 45);
//修改坐标原点和旋转角度
ctx.translate(x,y);
ctx.rotate(deg*Math.PI/180);
ctx.fillText(txt, 0,0);
//恢复坐标原点和旋转角度
ctx.rotate(-deg*Math.PI/180);
ctx.translate(-x,-y);
}
/**绘制干扰线**/
for(var i=0; i<8; i++){
ctx.strokeStyle = randomColor(40,180);
ctx.beginPath();
ctx.moveTo( randomNum(0,width), randomNum(0,height) );
ctx.lineTo( randomNum(0,width), randomNum(0,height) );
ctx.stroke();
}
/**绘制干扰点**/
for(var i=0; i<100; i++){
ctx.fillStyle = randomColor(0,255);
ctx.beginPath();
ctx.arc(randomNum(0,width),randomNum(0,height), 1, 0, 2*Math.PI);
ctx.fill();
}
}
</script>
</body>
</html>
重点是 <form action="${pageContext.request.contextPath}/user_login.action">
第五步:提交接收数据后数据校验返回
要在action中用service对象,在service中用dao对象,(先创建对象,然后实现set方法)在bean.xml配置注入
<!-- 第一步 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<!--注入sessionFactory-->
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 第二步 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- action特点是多实例的:scope="prototype" -->
<bean id="userAction" class="cn.itssh.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userService" class="cn.itssh.service.UserService">
<property name="userDao" ref="userDaoImpl"></property>
</bean>
<bean id="userDaoImpl" class="cn.itssh.dao.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
service类上@Transactional
dao接口实现类继承HibernateDaoSupport
- action
public String login(){
User userExist = userService.login(user);
if(userExist != null) {
//保持登录状态
HttpServletRequest request = ServletActionContext.getRequest();
request.getSession().setAttribute("user", userExist);
return "loginsuccess";
} else {
return "login";
}
}
- service return userDao.loginUser(user);
- dao
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
@SuppressWarnings("all")
public User loginUser(User user) {
List<User> list = (List<User>) this.getHibernateTemplate().find("from User where username=? and password=?",user.getUsername(),user.getPassword());
if(list != null && list.size() != 0) {
User u = list.get(0);
return u;
} else {
return null;
}
}
}
效果:(记得将struts中的class改为spring中配置的类名)