[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QHolCRBK-1586427080378)(C:\Users\you\AppData\Roaming\Typora\typora-user-images\image-20200408184924476.png)]
ORM映射:表-类映射
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
username=root
password=123
private static String driver;
private static String url;
private static String username;
private static String password;
static {//new 一个Properties对象来获取它的流
Properties properties = new Properties();
//通过类加载器读取资源并且转换成数据流
InputStream is = BaseDao.classshijisha.getClassLoader().getResourceAsStream("db.properties");
try {//load到了db.properties
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//现在可以开始调用db.properties中的对象了
driver = properties.getProperty("drive");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
//BaseDao.class实际上是做了一个反射其实java里面有一个class类,通过它可以实例一个对象,不用用new来创建对象
//getClassLoader是将BaseDao.class加载到jvm虚拟机中生成class类
io去读数据文件的复习
//先将db.properties变成数据流输入进来
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
properties.load(is);
//这样就把db.properties放入缓存区了
//然后做映射
//现在可以开始调用db.properties中的对象了
driver = properties.getProperty("drive");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//连接数据库的方法
public static Connection getconnection(){
Connection connection = null;
try {
//用Class.forName()注册驱动
Class.forName(driver);
//用DriverManager.getConnection连接数据库
connection = DriverManager.getConnection(url,username,password);
//此时连接操作已经完成 我们需要返回这个Connection对象 但是他被try catch包住了
} catch (Exception e) {
e.printStackTrace();
}
return connection;//提升connection的作用域之后就可以return了
}
//1.重写查询操作方法
public static ResultSet executeQuery(Connection connection,String sql,Object[] params,ResultSet rs ,PreparedStatement preparedStatement) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i <params.length ; i++) {//预编译
//for循环从0写但是setObject中的第一个参数是从1开始的 所以用+1
preparedStatement.setObject(i+1,params[i]);
}
//执行sql语句,预编译过了所以直接执行
rs = preparedStatement.executeQuery();
//返回executeQuery
return rs;
//将rs 和 preparedStatement提升作用域是为了之后的关闭资源方便
}
//编写增删改公共方法
public static int executeUpdata(Connection connection,String sql,Object[] params ,PreparedStatement preparedStatement) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i <params.length ; i++) {//预编译
//for循环从0写但是setObject中的第一个参数是从1开始的 所以用+1
preparedStatement.setObject(i+1,params[i]);
}
//执行sql语句,预编译过了所以直接执行
int updateRows = preparedStatement.executeUpdate();
//返回executeQuery
return updateRows;
//将rs 和 preparedStatement提升作用域是为了之后的关闭资源方便
}
//编写close方法,用boolean返回值是想看看关闭资源是否成功
public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet rs){
boolean flag = true;
if (rs!=null){
try {//关闭成功
rs.close();
//GC回收
rs=null;
} catch (SQLException e) {
e.printStackTrace();
//关闭出错
flag=false;
}
}
if (connection!=null){
try {//关闭成功
connection.close();
//GC回收
connection=null;
} catch (SQLException e) {
e.printStackTrace();
//关闭出错
flag=false;
}
} if (preparedStatement!=null){
try {//关闭成功
preparedStatement.close();
//GC回收
preparedStatement=null;
} catch (SQLException e) {
e.printStackTrace();
//关闭出错
flag=false;
}
}
return flag;
}
}
package com.you.filter;
import javax.servlet.*;
import java.io.IOException;
//更改字符编码
public class characterEncodingFliter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
web.xml
<filter>
<filter-name>characterEncodingFliterfilter-name>
<filter-class>com.you.filter.characterEncodingFliterfilter-class>
filter>
<filter-mapping>
<filter-name>characterEncodingFliterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
过滤器一定要写
filterChain.doFilter(servletRequest,servletResponse);
将过滤器传递下去(不要停下来啊!)
这时候基础的准备工作就做完了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ElDWjknM-1586427080381)(C:\Users\you\AppData\Roaming\Typora\typora-user-images\image-20200409113418519.png)]
观察并分析登录模块 理清逻辑
DAO(数据持久层)–>service(业务层)–>servlet(控制层)–>view视图层)
public interface UserDao {
//得到要登录用户
public User getLoginUser(Connection connection, String userCode,String userPassword) throws SQLException;
}
//创建UserDaoImpl实现用户登录的Dao接口
public class UserDaoImpl implements UserDao {
public User getLoginUser(Connection connection, String userCode, String userPassword) throws SQLException {
ResultSet rs = null;
PreparedStatement pstm = null;
User user = null;
if (connection != null) {//重要 如果没有请求连接也进行sql的查询会出大问题
//因为是用预编的方法所以参数用?
String sql = "select * from smbms_user where userCode=? and userPassword=?";
//还需要给sql语句传parms参数
Object[] params = {userCode, userPassword};
//这时候就可以调用BaseDao中的sql查询语句了
//得到查询返回的结果集 进行遍历全部取出来
rs = BaseDao.executeQuery(connection, pstm, rs, sql, params);
if (rs.next()){
user = new User();//创建一个user 设置user中的值
user.setId(rs.getInt("id"));
user.setUserCode(rs.getString("userCode"));
user.setUserName(rs.getString("userName"));
user.setUserPassword(rs.getString("userPassword"));
user.setGender(rs.getInt("gender"));
user.setBirthday(rs.getDate("birthday"));
user.setPhone(rs.getString("phone"));
user.setAddress(rs.getString("address"));
user.setUserRole(rs.getInt("userRole"));
user.setCreateBy(rs.getInt("createBy"));
user.setCreationDate(rs.getDate("creationDate"));
user.setModifyBy(rs.getInt("modifyBy"));
user.setModifyDate(rs.getDate("modifyDate"));
}
//设置完成之后关闭资源
BaseDao.closeResource(null,pstm,rs);
//conn不关是因为这只是登录用户的dao 还可能继续使用sql
}
return user;
}
}
public interface UserService {
//用户登录
public User login(String userCode,String userPassword);
}
public class UserServiceImpl implements UserService {
//业务层都会调取Dao层,所以我们要引入Dao层
private UserDao userDao;//私有化UserDao的对象
public UserServiceImpl(){
userDao = new UserDaoImpl();
//通过无参构造方法将userDao实例化 然后就可以使用userDao方法了
}
public User login(String userCode, String userPassword) {
Connection connection=null;//提升作用域
User user = null;//最后要返回User对象
connection = BaseDao.getconnection();//获取sql连接、
try {
//通过业务层调用对应的具体数据库操作
user = userDao.getLoginUser(connection,userCode,userPassword);
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return user;//调用这个方法就可以查到用户
}
// //测试一下功能
// @Test
// public void test(){
// //调用login方法
// UserServiceImpl service = new UserServiceImpl();
// User user = service.login("admin", "1237");
// System.out.println(user.getUserPassword());
// }
}
public class LoginServlet extends HttpServlet {
//servlet(控制层)调用业务层代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入loginservlet...");
//获取用户名和密码
String userCode = req.getParameter("userCode");
String userPassword = req.getParameter("userPassword");
//调用业务层去和数据库进行对比,这里没有选取私有化业务层对象 而是直接new一个对象
UserServiceImpl userService = new UserServiceImpl();
User user = userService.login(userCode, userPassword);//这里已经把登录的人查出来了并返回到user中了
if(user!=null){
//查有此用户可以登录
//将用户的信息传到session中
req.getSession().setAttribute(Constans.User_session,user);//将session换个名字 存在常用的静态工具包中方便修改
//跳转到内部主页
resp.sendRedirect("jsp/frame.jsp");
}else {
//查无此用户 无法登录
req.setAttribute("error","用户名或者密码不正确");//error对应login.jpg中的${error }
//转发回登录页面 顺带提示用户名或者密码错误
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
8.注册servlet
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.you.servlet.user.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
9.测试访问,确保以上功能成功
移除session 返回登录页面
public class logoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().removeAttribute(Constans.User_session);
//移除用户的session
resp.sendRedirect("/login.jsp");//返回登录页面
}
web.xml
<!--注销-->
<servlet>
<servlet-name>logoutServlet</servlet-name>
<servlet-class>com.you.servlet.user.logoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logoutServlet</servlet-name>
<url-pattern>/jsp/logout.do</url-pattern>
</servlet-mapping>
登录过滤器()
编写一个过滤器,并注册
public class LoginFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse)servletResponse;
HttpServletRequest req = (HttpServletRequest)servletRequest;
//过滤器从session中获取用户
User session = (User) req.getSession().getAttribute(Constans.User_session);
if (session==null){
//已经被移除或者注销了或者未登录
resp.sendRedirect("/smbms/error.jsp");
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
<filter>
<filter-name>LoginFilterfilter-name>
<filter-class>com.you.filter.LoginFilterfilter-class>
filter>
<filter-mapping>
<filter-name>LoginFilterfilter-name>
<url-pattern>/jsp/*url-pattern>
filter-mapping>
由此我们就在userDao中复写一个修改密码的方法
//修改当前用户密码
public int modifyPwd(Connection connection,String id,String userPassword)throws SQLException;
//修改用户密码
public int modifyPwd(Connection connection, String id, String userPassword) throws SQLException {
PreparedStatement pstm =null;
int i=0;
if(connection!=null) {
String sql = "update smbms_User set userPassword = ? where id = ?";
Object params[] = {userPassword, id};
i = BaseDao.executeUpdata(connection, sql, params, pstm);
BaseDao.closeResource(null, pstm, null);
}
return i;
}
}
//当前用户修改密码
public boolean modifyPwd(int id , String userPassword);
public boolean modifyPwd(int id, String userPassword) {
Connection connection=null;
boolean flag=false;
connection = BaseDao.getconnection();//获取数据库连接
try {//调用Dao层操作数据库
if ( userDao.modifyPwd(connection,id,userPassword)>0){
flag=true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return flag;
}
}
重写方法复用
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("savepwd")&&method!=null){
this.modifyPwd(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){
//获取要修改的密码和id
Object attribute = req.getSession().getAttribute(Constans.User_session);
String newpassword = req.getParameter("newpassword");
boolean flag = false;
//判断这个session和新密码是否存在
if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){
UserServiceImpl userService = new UserServiceImpl();
flag = userService.modifyPwd(((User) attribute).getId(), newpassword);
if(flag){
req.setAttribute("message","修改密码成功");
//密码修改成功移除当前session
req.getSession().removeAttribute(Constans.User_session);
}else {
req.setAttribute("message","密码修改失败");
}
}else{
//新密码有问题
req.setAttribute("message","新密码有问题");
}
try {
req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注册servlet
<servlet>
<servlet-name>UserServletservlet-name>
<servlet-class>com.you.servlet.user.UserServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>UserServletservlet-name>
<url-pattern>/jsp/user.dourl-pattern>
servlet-mapping>
1.阿里巴巴的fastjson
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.68version>
dependency>
2.后台代码修改(新增了一个判断旧密码的方法)
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("savepwd")&&method!=null){
this.modifyPwd(req,resp);
}else if (method.equals("pwdmodify")&&method!=null){
this.pwdmodify(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
//修改密码
public void modifyPwd(HttpServletRequest req, HttpServletResponse resp){
//获取要修改的密码和id
Object attribute = req.getSession().getAttribute(Constans.User_session);
String newpassword = req.getParameter("newpassword");
boolean flag = false;
//判断这个session和新密码是否存在
if(attribute!=null && !StringUtils.isNullOrEmpty(newpassword)){
UserServiceImpl userService = new UserServiceImpl();
flag = userService.modifyPwd(((User) attribute).getId(), newpassword);
if(flag){
req.setAttribute("message","修改密码成功");
//密码修改成功移除当前session
req.getSession().removeAttribute(Constans.User_session);
}else {
req.setAttribute("message","密码修改失败");
}
}else{
//新密码有问题
req.setAttribute("message","新密码有问题");
}
try {
req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//与旧密码进行比对
public void pwdmodify(HttpServletRequest req, HttpServletResponse resp){
//旧密码就存放在session中直接在session中获取
Object o = req.getSession().getAttribute(Constans.User_session);
//与其做对比的密码
String oldpassword = req.getParameter("oldpassword");
System.out.println(oldpassword);
//万能的Hashmap 一切的东西都可以存放进去
HashMap<String,String> resultMap= new HashMap<String,String>();//resultMap结果集
if (o==null){//session失效了
resultMap.put("result","sessionerror");//给结果集传ajax设置的result
}else if (oldpassword==null){
resultMap.put("result","error");//给结果集传ajax设置的result
}else{
//密码不为空且session也没有失效 我们就可以通过session进行比对了!
//同时因为设置的session为object的类型先要转换为User类型
String userPassword = ((User) o).getUserPassword();//session中用户的密码
if (oldpassword.equals(userPassword)){
System.out.println(oldpassword);
resultMap.put("result","ture");
}
else if(!oldpassword.equals(userPassword)){
resultMap.put("result","false");
}
}
try {//将数据以json的类型输出出去
resp.setContentType("application/json");//就像resp.setContentType("text/html")
//也是以流的形式去返回 注意关闭流的资源
PrintWriter writer = resp.getWriter();
//JSONArray是一个工具类,用于将数据类型转换为json类型
/*
*resultMap输出出来是{"result","sessionerror" , "result","error"}一对对的键值对 HashMap
* Json格式={key:value}
* */
writer.write(JSONArray.toJSONString(resultMap));
//最后刷新和关闭流资源
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}