根据前端登陆表单里面传过来的username和password值,去mysql数据库里面查询
select * from user where username=? and password=?
看看查出来的数据是null还是有值来判断登陆是否成功。
使用普通的JDBC的方式。
1、创建后台用户表user
2、创建java bean
package com.rtl.bean;
public class User {
private Integer id;
private String uname;
private String upwd;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", uname='" + uname + ''' +
", upwd='" + upwd + ''' +
'}';
}
}
3、创建接口:UserDao
package com.rtl.dao;
import com.rtl.bean.User;
public interface UserDao {
User getUserByNameAndPwd(String uName,String uPwd);
}
4、创建接口实现类:(这里实现了JDBC的连接)
package com.rtl.daoImpl;
import com.rtl.bean.User;
import com.rtl.dao.UserDao;
import java.sql.*;
public class UserDaoImpl implements UserDao {
@Override
public User getUserByNameAndPwd(String uName, String uPwd) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
User user = null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/servlet";
String name = "root";
String password = "root";
conn = DriverManager.getConnection(url, name, password);
String sql = "SELECt id,uname,upwd FROM user WHERe uname=? AND upwd=?";
ps = conn.prepareStatement(sql);
ps.setString(1,uName);
ps.setString(2,uPwd);
rs = ps.executeQuery();
if(rs.next()){
user = new User();
user.setId(rs.getInt(1));
user.setUname(rs.getString(2));
user.setUpwd(rs.getString(3));
return user;
}
}catch (Exception e){
e.printStackTrace();
}finally {
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return user;
}
}
5、写LoginServlet类;
package com.rtl.login.servlet;
import com.rtl.bean.User;
import com.rtl.dao.UserDao;
import com.rtl.daoImpl.UserDaoImpl;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String username = req.getParameter("username");
String password = req.getParameter("password");
UserDao userDao = new UserDaoImpl();
User user = userDao.getUserByNameAndPwd(username, password);
if(user != null){
out.println("success");
}else{
out.println("failed");
}
}
}
6、引入mysql连接器
7、web.xml配置文件:
login com.rtl.login.servlet.LoginServlet login /login
8、login.html
login
浏览器验证效果:
输入URL:
http://localhost:8080/login/login.html
进入登陆页面
输入admin和admin
点击登陆
输错了:
将数据库连接的获取封装成工具类。
1、右键src新建文件 db.properties
2、写ConnectionUtils
使用静态代码块读取配置文件db.properties
因为静态代码块只会执行一次。
再使用ThreadLocal技术,来保证同一个进程里面只有一个连接。
以往就是要一个连接就开一个,很浪费。
使用类加载器来读取db.properties配置文件。
不能使用之前的
props.load(new FileInputStream());
这种方式只是适合本地项目。
但是我们现在的项目以后是要部署到Tomcat服务器上运行。
所以必须采用以下方式读取文件。
使用类加载器读取文件
1、新建一个连接的工具类:
package com.rtl.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class ConnectionUtils {
private static String driver = null;
private static String url = null;
private static String username= null;
private static String password = null;
private static Properties props = new Properties();
private static ThreadLocal tl =new ThreadLocal<>();
static{
//
try {
InputStream is = ConnectionUtils.class.getClassLoader().getResourceAsStream("db.properties");
props.load(is);
driver = props.getProperty("jdbc.driver");
url = props.getProperty("jdbc.url");
username = props.getProperty("jdbc.username");
password = props.getProperty("jdbc.password");
//这个也是只会执行一次。所以也选择放在这里。
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConn() throws SQLException {
Connection conn = tl.get();
if(conn == null){
conn = DriverManager.getConnection(url, username, password);
tl.set(conn);
}
return conn;
}
public static void closeConn() throws SQLException {
Connection conn = tl.get();
if(conn != null){
conn.close();
}
tl.set(null);
}
public static void main(String[] args) throws SQLException {
Connection conn = ConnectionUtils.getConn();
System.out.println(conn);
}
}
2、配置文件:
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/servlet?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false jdbc.username=root jdbc.password=root
3、细节:jar包要要是这样的。
登陆的时候,错误的时候,直接再次进入登陆页面。
重定向的状态码:302
服务器会给浏览器发送一个302的状态码以及一个新的地址
if(user != null){
out.println("success");
}else{
resp.sendRedirect("login.html");
}
修改这里的代码。
现在就是:
登陆错误的时候,会重新回到登陆页面,但是
JSP技术是运行再服务器端的。
JSP可以写HTML代码,也可以写java代码,还有JSP标签
JSP本质就是Servlet
Servlet擅长处理业务
JSP擅长处理服务器页面
注意:
JSP页面是和html页面结构同级的。
他们都不在WEB-INF里面
1、随便写
2、写表达式。
表达式一定要给一个输出的结果。
解释JSP页面的执行原理。
HTML,css, js ,表达式代码呢?
通过输出流out.write()往出写
java代码呢?照搬!!
现在准备:
将原先登陆的页面由login.html换成login.jsp
使用jsp技术来展示页面。
那么,重定向的时候应该写成login.jsp
完全把login.html的代码换成login.jsp就行了。
新建login.jsp
修改LoginServlet里面登陆错误的时候,重定向到jsp里面。
浏览器:
http://localhost:8080/login/login.jsp
现在使用jsp页面展示登陆页面之后,我们还需要再
登陆失败的时候,不仅能够回到这个页面,还需要在用户名称后面写上一个提示:用户名或者密码错误。 这个即使叫做:转发技术。 一定要区分请求转发和请求重定向的区别。请求转发:是服务器内部的转发。
只能转发给当前服务器里面的某个组件
客户端浏览器向服务器发送了一个登陆请求,服务器中的Servlet只能处理,这个登陆是否成功。具体成功或者失败需要返回的页面交给JSP去做,JSP也是服务器这里的组件之一。所以请求转发是服务器内部的转发。
请求重定向:可以重定向到任何一个地方。
点击登陆,进入LoginServlet的doPost方法,里面使用response的sendRedirect方法,传入一个地址参数。这个就叫做重定向。
如果是登陆失败,再回到登陆页面,那就再写登陆页面的地址。
请求转发只有一次请求,一次请求就只有一个请求对象和响应对象。
需要将登陆失败这个信息绑定到request上面,然后由LogServlet传递给JSP。
三行代码:
1、修改LogServlet里面doPost()里面登陆失败的处理逻辑。
2、再次编写jsp页面。
jsp页面需要显示错误信息。
浏览器:
http://localhost:8080/login/login.jsp
发现一个问题:
还没登陆,第一次进入登陆页面就会出现这个null。
登陆
错误导致的,可以。
http://localhost:8080/login/login.jsp
进入登陆页面,右边出现null的问题。
之前的jsp:
现在的jsp:
解释:
刚才在jsp里面写java片段的时候:
<%
String logingMsg = (String)request.getAttribute("login_msg");
%>
这里的request对象是哪里来的?
JSP里面的内置对象。是从LoginServlet那边传过来的。
1、out:JspWriter
4、pageContext:相当于当前页面的上下文,jsp页面本质是一个Servlet,这个pageContext代表整个Servlet(在后面EL表达式有用到)
5、servletContext:整个web app只有一个
6、request:
7、response
8、session
实际开发中:
jsp页面中少出现java代码
EL是JSP内置的表达式语言。
EL的基本语法:
${}
EL表达式用来代替JSP的
<%=%>JSP里面的四大域对象:
1、最小的:
pageContext:代表当前整个JSP页面
2、
requestScope:
当前请求的域对象
3、sessionScope
当前会话的(后面讲)
4、applicationScope
整个web的,这个最大的域范围。
EL取对象的时候,没有指定,默认从小范围到大范围。
我们在登陆失败处理的时候:
将输出的提示错误信息,已经绑定到request对象里面去了
所以,后面EL表达式,应该获取requestScope这个域对象。
一个小细节就是:
使用EL表达式,不需要像前面写java代码那样判断是否log_msg为null
它会自动判断,有数据,输出,没有数据,啥也不输出。
现在功能实现了。
但是有个缺陷: 我登陆—>失败---->提示我用户名或者密码错误–>我重新点击文本框准备第二次输入账号密码,这个时候,右边的提示信息:用户名或者密码错误一直还在,这个很恶心。改进:在我准备第二次重新输入账号密码的时候,右边错误信息消失。
不要一直显示。
这个使用到的技术是:javascript
它可以写到HTML,也可以写到JSP里面。
由客户端浏览器来执行。
弱类型,



