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();
            }
        }
    
    
    }

     

  • 相关阅读:
    hdu 4027 Can you answer these queries?
    hdu 4041 Eliminate Witches!
    hdu 4036 Rolling Hongshu
    pku 2828 Buy Tickets
    hdu 4016 Magic Bitwise And Operation
    pku2886 Who Gets the Most Candies?(线段树+反素数打表)
    hdu 4039 The Social Network
    hdu 4023 Game
    苹果官方指南:Cocoa框架(2)(非原创)
    cocos2d 中 CCNode and CCAction
  • 原文地址:https://www.cnblogs.com/yumiaoxia/p/9032758.html
Copyright © 2011-2022 走看看