1.Servlet的介绍:
jsp的本质就是一个Servet,当jsp页面部署在web容器中,web容器会将jsp编译成Servlet。并且jsp页面中的内容都在Servlet中的service()中进行执行,故我们也可以撇开jsp页面,直接操作Servlet,当把Servlet当做表现层来使用,即直接在Servlet中进行页面的开发,对于静态的html标签的内容,我们要使用输出流来输出,虽然这样可以达到效果,但是开发效率会很低,因为所有的html标签,都是用Servlet的输出流来输出的,极其繁琐。并且撇开了jsp页面,美工人员也无法参与到Servlet的开发中来。故自MVC规范出现后,Servlet仅仅作为控制器(Controller)使用,不再需要生成html标签内容。
2.jsp与Servlet的区别:
1.Servlet中没有内置对象,原来jsp中的内置对象都要由程序显示的创建
2.对于静态的HTML标签,Servlet都必须要用输出流来逐行输出
3.jsp/Servlet的生命周期
jsp的本质就是Servlet,jsp页面将被Web容器编译成对应的Servlet,当Servlet在容器中运行的时候,其实例的创建和销毁都不是程序员控制的,而是由Web容器控制
创建Servlet实例有两个时机:
1.客户端第一次请求某个Servlet时,系统创建该Servlet的实例,大部分的Servelt都是这种Servlet
2.Web应用启动时立即创建Servlet实例,即load-on-startup Servlet
每个Servlet的生命周期:
(1)创建Servlet实例
(2)Web容器调用Servlet的init()方法,对Servlet进行初始化
(3)Servlet初始化后,将一直存在与容器中,用于响应客户端的请求。如果客户端发送get请求,容器调用Servlet的doGet方法处理并响应请求;如果客户端发送post请求,容器调用Servlet的goPost方法处理并响应请求。或者统一用service()方法来处理响应用户请求。
(4)Web容器决定销毁Servlet时,先调用Servlet的destroy()方法,通常在关闭Web应用之时销毁Servlet
Servlet的生命周期图:
4.使用Servlet作为控制器
在标准的MVC模式中,Servlet是仅作为控制器(Controller)使用的,下面通过一个登录验证的例子来进行熟悉
登录页面:
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2018/1/4 Time: 16:46 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录页面</title> </head> <body> <% if(request.getAttribute("errMsg") != null){ out.println("<span style=‘color:red‘>"+request.getAttribute("errMsg")+"</span><br/>"); } %> <form method="post" action="login"> 用户名:<input type="text" name="username"><br> 密 码:<input type="password" name="psw"/><br> <input type="submit" value="登录"/> </form> </body> </html>
控制器Controller代码:
/** * Description:servlet * Author: Eleven * Date: 2018/1/6 9:16 */ @WebServlet(name = "login",urlPatterns = {"/login"}) public class LoginServlet extends HttpServlet{ //响应客户端请求的方法 public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String errMsg = ""; //Servlet本身不能输出响应到客户端,必须请求转发到视图jsp页面 RequestDispatcher rd; //获取请求参数 String username = request.getParameter("username"); String psw = request.getParameter("psw"); //Servlet本身不处理任何业务逻辑,调用JavaBean处理用户请求 try{ DbDao dd = new DbDao("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/test","root","123456"); String sql = "select password from user where username = ?"; ResultSet rs = dd.query(sql,username); if(rs.next()){ //用户名和密码匹配 if(rs.getString("password").equals(psw)){ //将用户信息存在session中 HttpSession session = request.getSession(); session.setAttribute("username",username); //请求转发 rd = request.getRequestDispatcher("/jsp/welcome.jsp"); rd.forward(request,response); }else { //用户名和密码不匹配 errMsg = "用户名和密码不匹配,请重新输入!"; } }else{ //用户不存在 errMsg = "用户名不存在,请重新输入!"; } }catch (Exception e){ e.printStackTrace(); } if(errMsg != null && !errMsg.equals("")){ request.setAttribute("errMsg",errMsg); rd = request.getRequestDispatcher("/jsp/login.jsp"); rd.forward(request,response); } } }
DbDao的代码:
/** * Description:servlet * Author: Eleven * Date: 2018/1/6 9:27 */ public class DbDao { private Connection conn; private String driver; private String url; private String name; private String psw; public DbDao() { } public DbDao( String driver, String url, String name, String psw) { this.driver = driver; this.url = url; this.name = name; this.psw = psw; } //获取数据库连接 public Connection getConnection() throws Exception{ if(conn == null){ //注册驱动 Class.forName(driver); //获取连接 conn = DriverManager.getConnection(url,name,psw); } return conn; } //查询 public ResultSet query(String sql,Object... args) throws Exception{ //创建Statement PreparedStatement pstmt = getConnection().prepareStatement(sql); //设置参数 for(int i=0;i<args.length;i++){ pstmt.setObject(i+1,args[i]); } return pstmt.executeQuery(); } //插入 public boolean insert(String sql,Object... args) throws Exception{ PreparedStatement pstmt = getConnection().prepareStatement(sql); for(int i=0;i<args.length;i++){ pstmt.setObject(i+1,args[i]); } if(pstmt.executeUpdate() != 1){ return false; } return true; } //修改 public void modify(String sql,Object... args) throws Exception{ PreparedStatement pstmt = getConnection().prepareStatement(sql); for(int i=0;i<args.length;i++){ pstmt.setObject(i+1,args[i]); } pstmt.executeUpdate(); pstmt.close(); } //关闭数据库连接 public void closeConn() throws Exception{ if(conn != null && !conn.isClosed()){ conn.close(); } } public Connection getConn() { return conn; } public void setConn(Connection conn) { this.conn = conn; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPsw() { return psw; } public void setPsw(String psw) { this.psw = psw; } }