struts2 验证码+hibernate实现登陆验证、

基于struts2+hibernate+springssh2的登录验证码的实现
可以显示三种不同类型的验证码而不是单独一种,显示效果如下图所示:
* 第一种:简单验证码,4位随机数字 :
* 第二种:英文字符加数字的验证码 :
* 第三种:像铁路订票系统一样的验证码,肆+?=21
下面是实现的验证码类
package com.base.&
import java.awt.C&
import java.awt.F&
import java.awt.G&
import java.awt.image.BufferedI&
import java.io.ByteArrayInputS&
import java.io.ByteArrayOutputS&
import java.util.R&
import javax.imageio.ImageIO;&
import javax.imageio.stream.ImageOutputS&
&* 验证码类,主要生成几种不同类型的验证码&
&* 第一种:简单验证码,4位随机数字&
&* 第二种:英文字符加数字的验证码&
&* 第三种:像铁路订票系统一样的验证码,肆+?=21
&* @author 李朋飞
public class VerificationCodeUtil {&
&& private ByteArrayInputS// 图像&
&& private S// 验证码&
&& private static final int WIDTH = 80;&
&& private static final int HEIGHT = 20;&
&& public static void main(String[] arg) {&
&&&&&& VerificationCodeUtil vcu = VerificationCodeUtil.Instance();&
&&&&&& System.err.println(vcu.getVerificationCodeValue());&
&&& * 功能:获取一个验证码类的实例
&&& * @return
&& public static VerificationCodeUtil Instance() {&
&&&&&& return new VerificationCodeUtil();&
&& private VerificationCodeUtil() {&
&&&&&& BufferedImage image = new BufferedImage(WIDTH, HEIGHT,&
&&&&&&&&&&&&&& BufferedImage.TYPE_INT_RGB);&
&&&&&& int randomNum = new Random().nextInt(3);&
&&&&&& if (randomNum == 0) {&
&&&&&&&&&& initNumVerificationCode(image);&
&&&&&& } else if (randomNum == 1) {&
&&&&&&&&&& initLetterAndNumVerificationCode(image);&
&&&&&& } else {&
&&&&&&&&&& initChinesePlusNumVerificationCode(image);&
&&& * 功能:设置第一种验证码的属性
&& public void initNumVerificationCode(BufferedImage image) {&
&&&&&& Random random = new Random(); // 生成随机类&
&&&&&& Graphics g = initImage(image, random);&
&&&&&& String sRand = &&;&
&&&&&& for (int i = 0; i & 4; i++) {&
&&&&&&&&&& String rand = String.valueOf(random.nextInt(10));&
&&&&&&&&&& sRand +=&
&&&&&&&&&& // 将认证码显示到图象中&
&&&&&&&&&& g.setColor(new Color(20 + random.nextInt(110), 20 + random&
&&&&&&&&&&&&&&&&&& .nextInt(110), 20 + random.nextInt(110)));&
&&&&&&&&&& // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成&
&&&&&&&&&& g.drawString(rand, 13 * i + 6, 16);&
&&&&&& this.setStr(sRand);/* 赋值验证码 */&
&&&&&& // 图象生效&
&&&&&& g.dispose();&
&&&&&& this.setImage(drawImage(image));&
&&& * 功能:设置第二种验证码属性
&& public void initLetterAndNumVerificationCode(BufferedImage image) {&
&&&&&& Random random = new Random(); // 生成随机类&
&&&&&& Graphics g = initImage(image, random);&
&&&&&& String[] letter = { &A&, &B&, &C&, &D&, &E&, &F&, &G&, &H&, &I&, &J&,&
&&&&&&&&&&&&&& &K&, &L&, &M&, &N&, &O&, &P&, &Q&, &R&, &S&, &T&, &U&, &V&,&
&&&&&&&&&&&&&& &W&, &X&, &Y&, &Z& };&
&&&&&& String sRand = &&;&
&&&&&& for (int i = 0; i & 4; i++) {&
&&&&&&&&&& String tempRand = &&;&
&&&&&&&&&& if (random.nextBoolean()) {&
&&&&&&&&&&&&&& tempRand = String.valueOf(random.nextInt(10));&
&&&&&&&&&& } else {&
&&&&&&&&&&&&&& tempRand = letter[random.nextInt(25)];&
&&&&&&&&&&&&&& if (random.nextBoolean()) {// 随机将该字母变成小写&
&&&&&&&&&&&&&&&&&& tempRand = tempRand.toLowerCase();&
&&&&&&&&&&&&&& }&
&&&&&&&&&& }&
&&&&&&&&&& sRand += tempR&
&&&&&&&&&&& g.setColor(new Color(20 + random.nextInt(10), 20 + random&
&&&&&&&&&&&&&&&&&&& .nextInt(110), 20 + random.nextInt(110)));&
&&&&&&&&&&& g.drawString(tempRand, 13 * i + 6, 16);&
&&&&&&& }&
&&&&&&& this.setStr(sRand);/* 赋值验证码 */&
&&&&&&& g.dispose(); // 图象生效&
&&&&&&& this.setImage(drawImage(image));&
&&&& * 功能:设置第三种验证码属性 即:肆+?=24
&&& public void initChinesePlusNumVerificationCode(BufferedImage image) {&
&&&&&&& String[] cn = { &壹&, &贰&, &叁&, &肆&, &伍&, &陆&, &柒&, &捌&, &玖&, &拾& };&
&&&&&&& Random random = new Random(); // 生成随机类&
&&&&&&& Graphics g = initImage(image, random);&
&&&&&&& int x = random.nextInt(10) + 1;&
&&&&&&& int y = random.nextInt(30);&
&&&&&&& this.setStr(String.valueOf(y));&
&&&&&&& g.setFont(new Font(&楷体&, Font.PLAIN, 14));// 设定字体&
&&&&&&& g.setColor(new Color(20 + random.nextInt(10), 20 + random.nextInt(110),&
&&&&&&&&&&&&&&& 20 + random.nextInt(110)));&
&&&&&&& g.drawString(cn[x - 1], 1 * 1 + 6, 16);&
&&&&&&& g.drawString(&+&, 22, 16);&
&&&&&&& g.drawString(&?&, 35, 16);&
&&&&&&& g.drawString(&=&, 48, 16);&
&&&&&&& g.drawString(String.valueOf(x + y), 61, 16);&
&&&&&&& g.dispose(); // 图象生效&
&&&&&&& this.setImage(drawImage(image));&
&&& public Graphics initImage(BufferedImage image, Random random) {&
&&&&&&& Graphics g = image.getGraphics(); // 获取图形上下文&
&&&&&&& g.setColor(getRandColor(200, 250));// 设定背景色&
&&&&&&& g.fillRect(0, 0, WIDTH, HEIGHT);&
&&&&&&& g.setFont(new Font(&Times New Roman&, Font.PLAIN, 14));// 设定字体&
&&&&&&& g.setColor(getRandColor(160, 200)); // 随机产生165条干扰线,使图象中的认证码不易被其它程序探测到&
&&&&&&& for (int i = 0; i & 165; i++) {&
&&&&&&&&&&& int x = random.nextInt(WIDTH);&
&&&&&&&&&&& int y = random.nextInt(HEIGHT);&
&&&&&&&&&&& int xl = random.nextInt(12);&
&&&&&&&&&&& int yl = random.nextInt(12);&
&&&&&&&&&&& g.drawLine(x, y, x + xl, y + yl);&
&&&&&&& }&
&&& public ByteArrayInputStream drawImage(BufferedImage image) {&
&&&&&&& ByteArrayInputStream input =&
&&&&&&& ByteArrayOutputStream output = new ByteArrayOutputStream();&
&&&&&&& try {&
&&&&&&&&&&& ImageOutputStream imageOut = ImageIO&
&&&&&&&&&&&&&&&&&&& .createImageOutputStream(output);&
&&&&&&&&&&& ImageIO.write(image, &JPEG&, imageOut);&
&&&&&&&&&&& imageOut.close();&
&&&&&&&&&&& input = new ByteArrayInputStream(output.toByteArray());&
&&&&&&& } catch (Exception e) {&
&&&&&&&&&&& System.out.println(&验证码图片产生出现错误:& + e.toString());&
&&&&&&& }&
&&&& * 功能:给定范围获得随机颜色
&&& private Color getRandColor(int fc, int bc) {&
&&&&&&& Random random = new Random();&
&&&&&&& if (fc & 255)&
&&&&&&&&&&& fc = 255;&
&&&&&&& if (bc & 255)&
&&&&&&&&&&& bc = 255;&
&&&&&&& int r = fc + random.nextInt(bc - fc);&
&&&&&&& int g = fc + random.nextInt(bc - fc);&
&&&&&&& int b = fc + random.nextInt(bc - fc);&
&&&&&&& return new Color(r, g, b);&
&&&& * 功能:获取验证码的字符串值
&&&& * @return
&&& public String getVerificationCodeValue() {&
&&&&&&& return this.getStr();&
&&&& * 功能:取得验证码图片
&&&& * @return
&&& public ByteArrayInputStream getImage() {&
&&&&&&& return this.&
&&& public String getStr() {&
&&& public void setStr(String str) {&
&&&&&&& this.str =&
&&& public void setImage(ByteArrayInputStream image) {&
&&&&&&& this.image =&
struts2中获得验证码:
&* 功能:打开login.jsp的时候获得随机的验证码图片
&* @return
public String getRandomPictrue() {&
&& VerificationCodeUtil vcu = VerificationCodeUtil.Instance();&
&& this.setInputStream(vcu.getImage());&
&& ActionContext.getContext().getSession().put(&random&, vcu.getVerificationCodeValue());// 取得随机字符串放入HttpSession&
&&& return SUCCESS;&
另外前台jsp页面
& &script type=&text/javascript&&&&&&
&&& function changeValidateCode(obj) {&&&&
&&&&&&&&&& //获取当前的时间作为参数,无具体意义&&&&
&&&&&&& var timenow = new Date().getTime();&&&&
&&&&&&&&&& //每次请求需要一个不同的参数,否则可能会返回同样的验证码&&&&
&&&&&&& //这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。&&&&
&&&&&&& obj.src=&getRandomPictrue?d=&+&&&&
&/script&&
&&&&&&&&&&&&&&& &td height=&24& valign=&bottom&&&div align=&right&&&span class=&STYLE3&&验证码&/span&&/div&&/td&&
&&&&&&&&&&&&&&& &td width=&10& valign=&bottom&&&&/td&&
&&&&&&&&&&&&&&& &td width=&52& height=&24& valign=&bottom&&&input type=&text&& maxlength=4 name=&yzm& id=&textfield3& style=&width:50 height:17 background-color:#87 border:solid 1px #153966; ; color:#283439; &&&/td&&
&&&&&&&&&&&&&&& &td width=&92& valign=&bottom&&&div align=&center&&&img src=&getRandomPictrue.action& width=&80& height=&20& onclick=&changeValidateCode(this)&&&/div&&/td&&
&&&&&&&&&&&&& &/tr&&&
另外,在登录的时候,后台验证验证码是否输入正确
public String userLogin() {&
&&&&& String yanzhengma = this.getYzm().toLowerCase();//将验证码字符串全部转换成小写&
&&&&& String random = getSessionAttribute(&random&).toString().toLowerCase();&&&&&&&
&&&&& if(!yanzhengma.equals(random)){&
&&&&&&&&& this.setRequestAttribute(&errorMessage&, &验证码错误,请核实后重新输入&);&
&&&&&&&&& return INPUT;&
&&&&& else{&
&&&&&&&&& UserModel user = getUserService().loginJudge(getUserName(),&
&&&&&&&&&&&&&&&&&& getUserPass());&
&&&&&&&&&& if (user != null) {&
&&&&&&&&&&&&&& getSession().setAttribute(&user&, user);&
&&&&&&&&&&&&&& getSession().setAttribute(&userId&, user.getUserId());&
&&&&&&&&&&&&&& List&PermissionModel& treeList = userService.getTree(user&
&&&&&&&&&&&&&&&&&&&&&& .getUserId());&
&&&&&&&&&&&&&& getRequest().setAttribute(&treeList&, treeList);&
&&&&&&&&&&&&&& this.setRequestAttribute(&username&, user.getUserName());&
&&&&&&&&&&&&&& user.setLastLoginTime(DateUtil.getCurrentTimestamp());&
&&&&&&&&&&&&&& if (userService.addUser(user)) {&
&&&&&&&&&&&&&&&&&& (getUserName() + &登录成功&);&
&&&&&&&&&&&&&&&&&& return SUCCESS;&
&&&&&&&&&&&&&& } else {&
&&&&&&&&&&&&&&&&&& (getUserName() + &登录失败,失败原因,更新lastLoginTime失败&);&
&&&&&&&&&&&&&&&&&& this.setRequestAttribute(&errorMessage&, &服务器hold不住啦,请稍后重新登录&);&
&&&&&&&&&&&&&&&&&& return INPUT;&
&&&&&&&&&&&&&& }&
&&&&&&&&&& } else {&
&&&&&&&&&&&&&& (getUserName() + &登录失败,用户名或者密码不正确&);&
&&&&&&&&&&&&&& this.setRequestAttribute(&errorMessage&, &登录失败,用户名或者密码不正确&);&
&&&&&&&&&&&&&& return INPUT;&
&&&&&&&&&& }&
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
基于struts2+hibernate+spring(ssh2)的登录验证码的实现 1.只有数字 2.数字加字母 3.问题 Java代码
package com.base.
import java.awt.C
import java.awt.F
import java.awt.G
Struts2+hibernate实现用户登录和增删改查案例 开发工具MyEclipse 10.7.1 创建一个项目 web项目project. 部署好Struts2的开发环境:
1.引入需要的类库文件 jar
2.添加struts2的配置文件 struts.xml
:classespath:
3.在we ...
1.编写生成彩色验证码的Action类:CheckCode.java package com.dong.product.action. import java.awt.BasicS import java.awt.C import java.awt.F import java.awt.G impor ...
写在最前: 下午有招聘会,不想去,总觉得没有准备好,而且都是一些不对口的公司,可是又静不下心来,就来写个博客. 最近在仿造一个书城的网站: ,UI直接拿来用,前端后端自己写,目前大部分功能已经实现, 就把具体的登录注册功能拿来分享一下.PS:又写登录注册会不会被人喷啊=.=
一.开发环境的部署 程序结构: ...
一,使用Struts2标签库简化表单 在文章[基于Struts2框架实现登录案例]的基础上,通过使用Struts标签库可以简化登录页面login2.jsp 1 &%@ page language=&java& pageEncoding=&utf-8&%& 2 &%@ taglib prefix=&qu ...
日常的 Web 网站开发的过程中,为提升登录安全或防止用户通过脚本进行黄牛操作(宇宙最贵铁皮天朝魔都的机动车牌照竞拍中),很多网站在登录的时候,添加了验证码验证,而且验证码的实现越来越复杂,对其进行脚本识别的难度也越来越高.这对我们自动化脚本编写带了非常的不便,那么如何解决登录时的验证码问题呢?经常有初学自动化脚本编写的小主们问及此问题. 此文主要针对如何解 ...
关于如何利用Struts2,Hibernate,Spring开发电子商业汇票系统. 首先先说说电子商业汇票的种类: 1.电子银行承兑汇票 2.电子商业承兑汇票 另外电子商业汇票与纸票的区别: 电子商业汇票: 票号组成不同,电票号码30位长度. 发起渠道不同:电子商业汇票由企业客户在网上银行进行登记. 网络方式传输,而电子商业汇票以电子方式流通,采用计算机等电 ...
struts2+hibernate+spring的jar包. 总有听说jar包冲突. 今弄个不冲突的,还包括Mysql和Oracle的驱动,还有验证码的jar. 以上jar包的下载地址 http://download.csdn.net/source/1325320 本文出自 &wIsper 把技术做成艺术& 博客,转载请与作者联系!SSH整合教程(struts2+spring3+hibernate3)(含登陆示例)
让我们在令人燃烧的战斗音乐中开始整合SSH吧 :) 不喜欢也可以关掉 :(
准备工作:下载整合过程中需要的包/lb/5lbxlk60#lib.rar
115网盘礼包码:5lbxlk60
1.建立web项目
打开MyEclipse,我用的是8.6,项目名称就叫ssh好了,注意把项目语言统一设成utf-8。
完成之后的项目结构为:
2.把该加的包复制到项目里
找到项目所在文件夹,把下载的包复制粘贴到lib文件夹里,然后在MyEclipse里面刷新项目。
3.去数据库里建表,数据库我用的是mysql5.1
新建数据库,命名为ssh。
新建表user_info,sql如下:
CREATE TABLE `user_info` (
& `id` int(4) NOT NULL AUTO_INCREMENT,
& `username` varchar(30) NOT NULL,
& `password` varchar(20) NOT NULL,
& PRIMARY KEY (`id`),
& UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into user_info values(1,'a','a');
4.建立数据库连接,添加hibernate
在MyEclipse中,将视图切换到MyEclipse Database Explorer,新建一个数据库连接
点击“Add JARs”,选择项目中lib文件夹里的mysql-connector-java-5.0.6-bin.jar
接下来,可以点击“Next”选择要添加的数据库,也可以直接Finish。
在左侧双击刚才新增的数据库连接,输入密码,就可以看到ssh下面的user_info表了。
回到MyEclipse默认视图,为项目添加hibernate支持,右键点击项目名称-MyEclipse-Add Hibernate
Capabilities
然后点击finish,可能有些包已经存在了,没关系,下面继续。
在src下新建一个package,model.system。
回到数据库视图,右键点击user-info表,选择Hibernate Reverse Engineering
直接点Finish。这里为什么要选identity,请见附录说明。
现在可以看到已经添加好的文件,为了方便,现在开始ssh项目使用navigator视图(右键点项目-Show
In-Navigator)。
点开hibernate.cfg.xml看一下,它应该是这样子的:
5.修改web.xml
&?xml version="1.0"
encoding="UTF-8"?&
&web-app version="2.5"&
xmlns="/xml/ns/javaee"&
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&
xsi:schemaLocation="/xml/ns/javaee&
/xml/ns/javaee/web-app_2_5.xsd"&
&!-- spring相关配置 --&
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/applicationContext*.xml,classpath*:/context/applicationContext*.xml&/param-value&
&/context-param&
&listener&
&listener-class&
org.springframework.web.context.ContextLoaderListener
&/listener-class&
&/listener&
& &!-- 以下3项参数与log4j的配置相关
&context-param&
&param-name&log4jConfigLocation&/param-name&
&param-value&/WEB-INF/log4j.properties&/param-value&
&/context-param&
&context-param&
&param-name&log4jRefreshInterval&/param-name&
&param-value&60000&/param-value&
&/context-param&
&listener& &
& &listener-class&
org.springframework.web.util.Log4jConfigListener
& &/listener-class&
&/listener& &
& &!-- struts2相关配置
&filter-name&struts2&/filter-name&
&filter-class&org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&/filter-class&
&filter-mapping&
&filter-name&struts2&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
&filter-mapping&
&filter-name&struts2&/filter-name&
&url-pattern&*.jsp&/url-pattern&
&/filter-mapping&
&welcome-file-list&
&welcome-file&index.jsp&/welcome-file&
&/welcome-file-list&
&/web-app&
6.添加applicationContext.xml
在WEB-INF下新建applicationContext.xml文件
内容如下:
&?xml version="1.0"
encoding="UTF-8"?&
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"&
&!--指明hibernate配置文件的位置
&bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&
& &&property
name="configLocation" value="classpath:hibernate.cfg.xml"
&!--定义DAO
&bean id="userDao"
class="dao.system.UserDao"&
& &&property
name="sessionFactory"&&
bean="sessionFactory"/& &
&&/property&
&!-- & 配置LoginAction.java类文件
&bean id="LoginAction"
class="action.login.LoginAction"
scope="prototype"&
&property name="userService" ref="userService"
配置service层 --&
&bean id="userService"
class="service.system.UserService"&
& &property
name="userDao"&
bean="userDao"/&
&/property&
7.添加spring支持
右键点击项目-MyEclipse-Add Spring Capabilities
记得选上Spring 3.0 Web Libraries。
选择刚才新建的applicationContext.xml文件
点击Finish。
8.添加dao,service和action
结构如下:
UserDao.java内容如下:
package dao.
import java.util.L
org.springframework.orm.hibernate3.support.HibernateDaoS
import model.system.UserI
public class UserDao extends HibernateDaoSupport{
public void add(UserInfo m)
getHibernateTemplate().save(m);
@SuppressWarnings("unchecked")
public List&UserInfo&
showAllUsers()
return getHibernateTemplate().find("from user");
public void update(UserInfo m)
& getHibernateTemplate().update(m);
public void delete(String id)
getHibernateTemplate().delete(getHibernateTemplate().get(UserInfo.class,
public UserInfo getUserById(String id)
m=(UserInfo)getHibernateTemplate().get(UserInfo.class, id);
//普通用户登录验证
@SuppressWarnings("unchecked")
public boolean checkUser(String userName,String
userPassword){
& boolean flag =
& String hql = "from UserInfo as user where
user.username = '"+userName+"' and user.password =
'"+userPassword+"'";
List&UserInfo& userList =
this.getHibernateTemplate().find(hql);
& if(userList.size()&0){
UserService.java内容如下:
package service.
import dao.system.UserD
public class UserService{
private UserDao userD
public boolean checkUser(String userName,String
userPassword)
return userDao.checkUser(userName, userPassword);
public UserDao getUserDao() {
return userD
public void setUserDao(UserDao userDao) {
this.userDao = userD
LoginAction.java内容如下:
package action.
import com.opensymphony.xwork2.ActionS
import service.system.UserS
public class LoginAction extends ActionSupport{
private static final long serialVersionUID =
private UserService userService = new UserService();
public UserService getUserService() {
return userS
public void setUserService(UserService userService) {
this.userService = userS
public String getUsername() {
public void setUsername(String username) {
& this.username =
public String getPassword() {
public void setPassword(String password) {
& this.password =
public String execute(){
boolean flag =
if (username == null || username.trim().equals("")) {
this.addFieldError("username", "用户名不能为空");
return "fail";
} else if (password == null || password.trim().equals(""))
this.addFieldError("password", "密码不能为空");
return "fail";
flag = userService.checkUser(username, password);
if (flag) {
return "success";
return "fail";
9.添加struts支持
右键点击项目-MyEclipse-Add Struts
Capabilities
其他的选默认就行,然后Finish。
10.修改struts.xml
&?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"&
&!--下述语句是将struts2交给spring管理
&constant name="struts.objectFactory"
value="spring" /&
&!--将action内容放在package元素下,package元素的name值与extends值可以使用默认值,如下所示
&package name="ssh"
extends="struts-default"&
&!--例如与用户登录相关的LoginAction,配置如下,其中,class值与applicationContext.xml文件中该action的id值相对应,name值作为标识--&
& & &action
name="loginAction" class="LoginAction"&
&!--result元素设置页面跳转值,其中name值为目标页面的字符串标识,如下,登录失败时回到fail.jsp页面,成功时,转向success.jsp页面
& & &result
name="fail"&/jsp/login/fail.jsp&/result&
& & &result
name="success"&/jsp/login/success.jsp&/result&
&/package&
11.添加页面
累了吧?快成功了,下面继续。
在WebRoot文件夹下面新建一个jsp文件夹,存放页面。
结构如下:
fail.jsp内容如下:
&%@ page language="java"
pageEncoding="utf-8"%&
String path = request.getContextPath();
String basePath =
request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
&!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"&
href="&%=basePath%&"&
&title&Fail&/title&
登陆失败。&br&
success.jsp内容如下:
&%@ page language="java"
pageEncoding="utf-8"%&
String path = request.getContextPath();
String basePath =
request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
&!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"&
href="&%=basePath%&"&
&title&Success&/title&
登陆成功。&br&
修改index.jsp,内容如下:
&%@ page language="java"
pageEncoding="utf-8"%&
&!-- 导入struts2标签库 --&
&%@taglib uri="/struts-tags"
prefix="s"%&
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" +
request.getServerPort()
+ path + "/";
&&title&用户登录&/title&
&div id="login"&
& & &s:form
action="loginAction" method="post"&
&&s:textfield label="用户名"
name="username"&&/s:textfield&
&&s:password label="密码"
name="password"&&/s:password&
&&s:submit
value="登录"&&/s:submit&
12.新增log4j.properties文件
放在WEB-INF下
内容如下:
#newhappy &log4j.properties start
log4j.rootLogger=DEBUG,myConsole,R
#console appender
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=%5p [%t]
(%F:%L) -%m%n
log4j.appender.myConsole.threshold=INFO
# R is set to be a
DailyRollingFileAppender.&
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender&
log4j.appender.R.File=D\:\\workspaces\\job\\job\\WebRoot\\WEB-INF\\backup.log&
log4j.appender.R.DatePattern =
'.'yyyy-MM-dd&
log4j.appender.R.layout=org.apache.log4j.PatternLayout&
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd
HH\:mm\:ss} [%c]-[%p] %m%n&
log4j.appender.R.threshold=INFO
#rolling file appender
#log4j.appender.myLogFile=org.apache.log4j.RollingFileAppender
#log4j.appender.myLogFile.File=mylog.log
#log4j.appender.myLogFile.MaxFileSize=500KB
#log4j.appender.myLogFile.MaxBackupIndex=2
#log4j.appender.myLogFile.layout=org.apache.log4j.PatternLayout
#log4j.appender.myLogFile.layout.ConversionPattern=%d{mmm
d,yyyy hh:mm:ss a} : %p [%t] %m%n
#log4j.appender.myLogFile.threshold=ERROR
#newhappy log4j.properties end
log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug
### log just the SQL
#log4j.logger.org.hibernate.SQL=debug
### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug
log4j的配置是从网上找的,如果有问题再自己调一下吧。
13.运行调试
配置好tomcat,然后发布,运行一下看看。
没关系,因为起初先导入了一些包,后期又分别添加了hibernate,srping和struts,所以可能有包重复了。
解决办法:先关掉MyEclipse,找到项目所在文件夹,把lib里面的包全部删除,换上我们一开始下载的那些包。别忘了把tomcat下webapps/ssh,lib里面的包也全部更换。这样应该就不会报错了。
就知道你懒得一步步搭环境,想要这个ssh小项目的源代码,请往右看-&/lb/5lbxl190#
&115网盘礼包码:5lbxl190
14.可能出错的地方
本来看上去很简单的过程,我才不告诉你我居然折腾了快两个星期呢。
一开始我没有自己导入包,按照网上的一个教程,全部是用MyEclipse自带的,自动生成的applicationContext.xml文件放在src文件夹下,然后web.xml里面写的是:
&param-name&contextConfigLocation&/param-name&
&param-value&classpath*:/applicationContext*.xml&/param-value&
这样写似乎是无法找到src下的这个配置文件,于是我的struts和spring一直整合不成功,后来看了这个帖子:
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/applicationContext*.xml,classpath*:/context/applicationContext*.xml&/param-value&
整合过程中可能出现的问题基本是就是这样,要么是包冲突、包重复、包缺失,要么就是配置文件找不到,或者文件路径不对。&
前面还有一点遗留问题,ID的generator为什么要选identity呢?
我之前找到的一个关于整合SSH的PPT里是这样解答的:
Hibernate中,&id&标签下的可选&generator&子元素是一个Java类的名字,用来为该持久化类的实例生成惟一标示,所有的生成器都实现net.sf.hibernate.id.IdentifierGenerator接口。这是一个非常简单的接口,某些应用程序可以选择提供它们自己的特定实现。当然,Hibernate提供了很多内置的实现。
下面是一些内置主键生成器(Key Generator):
1)assigned
主键由外部程序负责生成,无需Hibernate参与。
让应用程序在save()之前为对象分配一个标示符。
&generator&元素没有指定时的默认生成策略。
2)hilo通过hi/lo
算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
使用一个高/低位算法高效的生成long, short或者int类型的标识符。
给定一个表和字段(默认分别是hibernate_unique_key
和next_hi)作为高位值的来源。&
高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
3)seqhilo与hilo 类似,通过hi/lo
算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
使用一个高/低位算法来高效的生成long, short 或者
int类型的标识符,给定一个数据库序列(sequence)的名字。&
4)increment
主键按数值顺序递增此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。
这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常因此,如果同一数据库有多个实例访问,此方式必须避免使用。
用于为long,short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。在集群下不要使用。
5)identity
采用数据库提供的主键生成机制如DB2 SQL Server MySQL中的主键生成机制。
对DB2,MySQL, MS SQL Server,
Sybase和HypersonicSQL的内置标识字段提供支持。&
返回的标识符是long, short 或者int类型的。
6)sequence
采用数据库提供的sequence机制生成主键如Oralce中的Sequence。
在DB2,PostgreSQL, Oracle, SAP DB,
McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。
返回的标识符是long, short或者 int类型的。
7)native由Hibernate根据底层数据库自行判断,采用identity
hilo sequence其中一种作为主键生成方式。
8)uuid.hex用一个128-bit的UUID算法生成字符串类型的标识符,
这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32
的字符串表示)作为主键例如:5abefd3890cat33llsica3ee43bk222
9)uuid.string
与uuid.hex
类似,只是生成的主键未进行编码(长度16),在某些数据库中可能出现问题(如PostgreSQL)。
在MS SQL Server
中使用数据库生成的GUID字符串。
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
12)foreign
使用另外一个相关联的对象的标识符。通常和&one-to-one&联合起来使用。&
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。另外由于常用的数据库,如Oracle DB2
SQLServer MySql 等,都提供了易用的主键生成机制(Auto-Increase
字段或者Sequence)。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。
数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了较大影响因此,对于并发Insert要求较高的系统,推荐采用uuid.hex
作为主键生成机制。
最后,对于本文所讲的整合方法有任何疑问,欢迎大家留言进行讨论!
我的更多文章:
( 11:24:08)( 14:09:02)( 16:06:27)( 09:41:30)( 20:05:49)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 struts2 验证码 的文章

 

随机推荐