zoukankan      html  css  js  c++  java
  • Servlet开发

    自MVC规范出现后,Servlet的责任开始明确下来,仅仅作为控制器使用,不再需要生成页面标签,也不再做为视图层角色使用。servlet通常被称为服务器端小程序,是运行在服务器端的程序 。用于处理用户的请求及响应。

    一. Servlet 介绍

    Servlet是特殊的Java类,这个Java类必须继承HTTPServlet,每个servlet可以响应用户的请求。Servlet提供不同的方法用于相应用户的请求

    • doGet():用于相应客户端的get请求
    • doPost():用于响应客户端的Post请求
    • doPut():用于相应客户端的put请求
    • doDelete():用于相应客户端的delete请求

    事实上,客户端请求通常只有get和post两种,servlet为了响应这两种请求,必须重写doPost()和doGet()两个方法。

    大部分时候,servlet对于所有请求的响应都是都是完全一样的。因此可以采用重写一个方法来代替上面四个方法:只需要重写service方法即可响应客户端所有请求。

    另外,HTTPServlet还包括另外两个方法

    • init(ServletConfig config):创建servlet实例时,使用该方法初始化Servlet资源。
    • destroy():销毁Servlet实例时,自动调用该方法回收资源

    通常无需重写这两个方法。除非需要初始化Servlet时,完成某些资源初始化的方法,才考虑重写init()方法。如果需要在销毁Servlet之前,先完成某些资源的回收,比如关闭数据库连接等,才需要重写destroy方法。

    Servlet与JSP的区别在于:

    • Servlet没有内置对象,原JSP中的内置对象必须由程序显示创建
    • 对于静态的HTML标签,servlet必须使用页面输出流逐行输出

    二. Servlet 配置

     编辑好的servlet源文件并不能响应用户请求,还必须将其编译成class文件  。将编译后的class文件放在WEB-INF/classes路径下,如果servlet有包,则还应该将class文件放在对应的包路径下。

    为了让Servlet响应用户请求,还必须将Servlet配置在web应用中。配置Servlet时,需要修改web.xml文件》

    从servlet3.0开始,配置servlet的两种方式

    • 在servlet类中使用@webServlet注解进行配置
    • 通过在web.xml文件中进行配置 

    使用注解@webServlet配置Servlet时,常用的属性有

     

    @webServlet支持的常用属性
    属性 是否必须 说明
    asynsSupported 指定该Servlet是否支持异步操作模式
    displayName

    指定该Servlet的显示名

    initParam 用于为该Servlet配置参数
    loadOnStartup 用于将该servlet配置成load-on-startup 的 Servlet
    name 指定该servlet的名字
    urlPatterns/value 都指定servlet处理的URL  

     

     

     

     

     

     

     

     

     

    如果打算使用注解来配置Servlet,有两点需要指出:

    • 不要在web.xml文件的根元素(<web-app.../>)中指定metadata-complete="true".
    • 不要在web.xml文件中配置该servlet。

    如果打算使用web.xml文件来配置该Servlet,则需要配置如下两个部分。

    • 配置Servlet的名字:对应web.xml文件中的<servlet/>元素
    • 配置servlet的URL,对应web.xml文件中的<servlet-mapping/>元素。这一步是可选的。但如果没有为Servlet配置URL,则该servlet不能响应该用户请求。

    三. JSP/Servlet 的生命周期

    当Servlet在容器中运行时,其实例的创建及销毁等都不是程序员决定的,而是由web容器进行控制的的

    创建servlet实例有两个时机

    • 客户端第一次请求某个Servlet时,系统创建该Servlet的实例:大部分的Servlet都是这种Servlet
    • Web应用启动时立即创建Servlet实例,即load-on-startup Servlet.

    每个Servlet运行都遵循如下生命周期

    1. 创建Servlet实例
    2. Web容器调用Servlet的init方法,对Servlet进行初始化。
    3. Servlet初始化后,将一直保存在容器中,用于响应客户端的请求,调用doGet()或者doPost()方法处理并响应请求,或者统一使用service方法
    4. web容器决定销毁Servlet时,先调用Servlet的destroy()方法,通常在关闭Web应用时销毁Servlet。

    四. load-on-startup Servlet

    应用启动时就创建的Servlet通常是用于某些后台服务的Servlet,或者拦截很多请求的Servlet,这种Servlet通常作为应用的基础Servlet使用,提供重要的后台服务。

    配置load-on-startup的Servlet有两种方式

    • 在web.xml文件中通过<servlet.../>的子元素<load-on-startup.../>进行配置
    • 通过@webServlet注解的loadOnStartup属性指定

    <load-on-startup.../>元素和loadOnStartup属性都只接受一个整型值,这个整型值越小,Servlet越优先实例化

    五. 访问servlet的配置参数

    配置Servlet时,还可以增加额外的配置参数。通过使用配置参数,可以实现提供更好的可移植性,避免将参数以硬代码的方式写在代码程序中。

    设置参数的两种方式

    • 通常@webServlet 的initParam属性来指定
    • 通过在web.xml文件的<servlet.../>元素中添加<init-param.../>指定

    访问Servlet参数通过servletConfig对象完成,ServletConfig提供如下方法。

    String getInitParamter(String name):用于获取初始化参数

    六. 使用Servlet作为控制器

    在标准的Java EE的MVC设计模式中Servlet仅作为控制器使用。JSP作为表现层技术,其作用有两点

    • 负责收集用户请求参数
    • 将应用的处理结果,状态数据呈现给用户

    servlet仅充当控制器角色,它的作用类似于调度员;所有用户请求都发给Servlet,Servlet调用Model来处理用户请求,并调用JSP来呈现处理结果;或者Servlet直接调用JSP将应用的状态数据呈现给用户

     model通常由JavaBean充当,所有业务逻辑,数据访问逻辑都在model中实现。事实上,隐藏在Model下的可能还有很多丰富的组件,例如dao组件,领域对象等,下面介绍了一个使用Servlet作为控制器的MVC应用,该应用演示了一个简单的登录验证。

    <%@ page contentType="text/html;charset=UTF-8" language="java"  errorPage="" %>
    <html>
    <head>
        <title>new document</title>
    </head>
    <body>
    <span style="color:red;font-weight: bold;">
        <%
        if(request.getAttribute("err") != null){
            out.println(request.getAttribute("err")+"<br/>");
        }
        %>
    </span>
    请输入用户名和密码:<br/>
    <form id="login" method="post" action="login">
        用户名: <input type="text" name="username"><br/>&nbsp;&nbsp;码:<input type="password" name="pass"/><br/>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>
    package java.gdut.servlet;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.sql.ResultSet;
    
    @WebServlet(name = "login",urlPatterns = "/login")
    public class LoginServlet extends javax.servlet.http.HttpServlet {
        protected void service(javax.servlet.http.HttpServletRequest request,
                               javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
            String errMsg = "";
            RequestDispatcher rd;
            String username = request.getParameter("username");
            String pass = request.getParameter("pass");
            try{
                DbDao db = new DbDao("jdbc:mysql://localhost:3306/tb_test","com.mysql.jdbc.Driver","sherman","a123");
                ResultSet rs = db.querry("select pass from user_inf where name=?",username);
                if(rs.next()){
                    if(rs.getString("pass").equals(pass)){
                        HttpSession session = request.getSession(true);
                        session.setAttribute("name",username);
                        rd=request.getRequestDispatcher("/welcome.jsp");
                        rd.forward(request,response);
                    }else{
                        errMsg+="您的用户密码不符合,请重新输入";
                    }
                }else{
                    errMsg+="您的用户名不存在,请先注册";
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            if(errMsg != null && !errMsg.equals("")){
                rd = request.getRequestDispatcher("/login.jsp");
                request.setAttribute("err",errMsg);
                rd.forward(request,response);
            }
        }
    
    
    }
    package java.gdut.servlet;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    public class DbDao {
        private Connection conn;
        private String url;
        private String driver;
        private String user;
        private String pass;
    
        public DbDao(String url, String driver, String user, String pass) {
            this.url = url;
            this.driver = driver;
            this.user = user;
            this.pass = pass;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getDriver() {
            return driver;
        }
    
        public void setDriver(String driver) {
            this.driver = driver;
        }
    
        public String getUser() {
            return user;
        }
    
        public void setUser(String user) {
            this.user = user;
        }
    
        public String getPass() {
            return pass;
        }
    
        public void setPass(String pass) {
            this.pass = pass;
        }
    
        /**
         * 获取数据库连接
         */
        public Connection getConn() throws Exception {
            if (conn == null) {
                Class.forName(this.driver);
                conn = DriverManager.getConnection(this.url, this.user, this.pass);
                System.out.println(conn);
            }
            return conn;
        }
    
        /**
         * 执行插入
         * @param sql
         * @param args
         * @return
         * @throws Exception
         */
        public boolean insert(String sql,Object... args) throws Exception{
            PreparedStatement prst = getConn().prepareStatement(sql);
            for (int i = 0; i <args.length ; i++) {
                prst.setObject(i+1,args[i]);
            }
            if(prst.executeUpdate() != 1){
                return false;
            }
    
            return true;
        }
    
        /**
         * 执行查询
         * @param sql
         * @param args
         * @return
         * @throws Exception
         */
        public ResultSet querry(String sql,Object... args)throws Exception{
            PreparedStatement prst = getConn().prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                prst.setObject(i+1,args[1]);
            }
            return prst.executeQuery();
        }
    
        public void modify(String sql,Object... args)throws Exception{
            PreparedStatement prst = getConn().prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                prst.setObject(i+1,args[1]);
            }
            prst.executeUpdate();
            prst.close();
        }
    
        public void closeConn()throws Exception{
            if(null != conn && !conn.isClosed()){
                conn.close();
            }
        }
    
    
    }

     

  • 相关阅读:
    css文本在标签<text>内平均分布
    ES6实现去重,排序,加升序
    uni-app项目打包成小程序
    uni-app项目( uniapp滚动监听元素)
    运行vue项目:Module build failed: Error: Cannot find module 'node-sass'报错问题
    笨方法实现数量的输入与加一减一 、以及对边界值的判断禁用
    基于nuxt的前端商城pc端项目(bug记录)
    基于nuxt的商城项目pc端项目记录
    Vue学习笔记整理-长期更新
    程序员,不要创业!
  • 原文地址:https://www.cnblogs.com/yumiaoxia/p/9032758.html
Copyright © 2011-2022 走看看