解决漏洞
1、问题探索:
昨天写的用户注册登录系统中存在漏洞,如下:在登陆界面下,当输入密码时时有 sdef’ or 1=’1 等类似的情况时,不论原密码是否正确都会登录成功。原因是:该处出现了1=1这个正确的结论,这也是90年的黑客问题。
2、解决办法:
接口 PreparedStatement
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
注:用于设置 IN 参数值的设置方法(setShort、setString 等等)必须指定与输入参数的已定义 SQL 类型兼容的类型。例如,如果 IN 参数具有 SQL 类型 INTEGER,那么应该使用 setInt 方法。
代码如下:
try {
if (!con.isClosed()) {
PreparedStatement state = con.prepareStatement("select * from user where user_name=? and password=?");
state.setString(1, Username);
state.setString(2, password);
ResultSet set = state.executeQuery();
set.last();
int num = set.getRow();
System.out.println("查询结果:" + num);
事务
事务(一组不可拆分的操作) 例如ATM取款 中间任何一个过程失败,前面的过程全都恢复操作
之前的状态。
在此,提出了事务这一词,在一个过程需要多条语句执行时,往往用到事务,例如添加用户时:
public class Commit {
public static void main(String[] args) {
//添加4个用户用户
String s1 = "insert into user(user_name,password)value('lili','123456')";
String s2 = "insert into user(user_name,password)value('lgr','12y456')";
String s3 = "insert into user(user_nae,password)value('lcvg','123ui56')";//这里name故意写错
String s4 = "insert into user(user_name,password)value('frgtli','123r6')";
Connection con = SQLManager.newInstance().getCon();// 与数据库建立连接
// 数据库操作类
try {
Statement state = con.createStatement();//数据库连接默认为每一条语句都是一个事务,会单独执行
con.setAutoCommit(false);//首先设置connection不自动提交
//execute(s1)效率比较低
state.addBatch(s1);//执行多条语句用addBath
state.addBatch(s2);
state.addBatch(s3);//执行到此时,发生错误,上面的s1,s2也不能添加进库中
state.addBatch(s4);
state.executeBatch();
con.commit();//// 使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
eclipse JavaEE web搭建环境
1、首先将下面这个jar文件放到安装的eclipse的plugins文件夹下
然后重新启动eclipse就会出现这样的三个图标:
2、选择JavaEE,创建Servlet工程,导入jar包等等一系列详细的步骤就不多说了,没有技术含量,可以问度娘……
3、找到WebContent文件夹,在其中点右键建立新的index.html问价
完成后出现如下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a>ho,hhh(可以以随便输入)</a>
</body>
</html>
单例设计模式
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。
private static SQLManager manager;
public static synchronized SQLManager newInstance() {
if (manager == null) {
manager = new SQLManager();
}
return manager;
}
MVC设计模式
编程思想 modle view control 数据 界面 控制全部分开
例如在用户注册登录代码中,将注册和登陆的方法写到一个控制类中,在界面中直接调用
####Java代码如下
//操作类
public class SQLOperate {
private static SQLOperate operate;
private SQLOperate() {
}
//设置单例
public static synchronized SQLOperate newInstance() {
if(operate==null){
operate = new SQLOperate();
}
return operate;
}
public boolean signIn(String Username, String password) {//这是用户登陆方法
Connection con = SQLManager.newInstance().getCon();
try {
if (!con.isClosed()) {
PreparedStatement state = con.prepareStatement("select * from user where user_name=? and password=?");
state.setString(1, Username);
state.setString(2, password);
ResultSet set = state.executeQuery();
set.last();
int num = set.getRow();
System.out.println("查询结果:" + num);
return num == 1;
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
public void register(String Username,String password){//这是注册方法
Statement state = SQLManager.newInstance().getStatement();
String sql = "select * from user where user_name='" + Username + "'";
try {
ResultSet set = state.executeQuery(sql);// 运行给定的 sql
// 语句并返回单一的
// ResultSet 对象。
set.last();// 游标移到最后一行
int num = set.getRow();// 得到Username的行号
if (num > 0) {
System.out.println("已存在");
} else {
String login = "insert into user(user_name,password)value('" + Username + "','" + password
+ "')";
state.execute(login);
System.out.println("注册成功!");
// return num == 1;
}
// return num == 1;
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//return false;
}
注册时调用操作类中的注册方法:
btnNewButton = new JButton("注册");
btnNewButton.setBounds(103, 170, 93, 23);
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String Username = textFieldUserName.getText();
String password = textFieldPassword.getText();
SQLOperate.newInstance().register(Username, password);
用户登录时调用操作类的登陆方法:
public void actionPerformed(ActionEvent e) {
String Username = textFieldUsername.getText();
String password = textFieldPassword.getText();
boolean isSignIn = SQLOperate.newInstance().signIn(Username,password);
if(isSignIn){
System.out.println("登陆成功");
}else{
System.out.println("用户名或密码错误");
}
工厂设计模式
客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:前面写到的消费者消费和生产者生产产品的程序,详细的请看本人博客(8.05)
观察者模式
观察者模式定义了一种一队多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
此模式在后面的Android中将会详细介绍。