Servlet学习

1.部署环境

使用工具:IDEA、tomcat、maven

        新建一个maven项目。在maven项目中导入servlet依赖        

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        新建一个HelloServlet类进行测试。

public class HelloServlet extends HttpServlet {

    //get和post只是实现请求的不同方式,可以互相调用,业务逻辑一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter();//响应流
        writer.print("hello servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

         在web.xml文件中注册该servlet

<!--注册servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.leo.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

        之后发布tomcat进行测试

         结果:

   环境已经部署完成,接下来开始学习。

2. 注册servlet

<servlet>
        <servlet-name>hello</servlet-name>//给该servlet起个名字,自定义
        <servlet-class>com.leo.servlet.HelloServlet</servlet-class>//绑定该servlet类
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>//对应上面servlet的名字
        <url-pattern>/hello</url-pattern>//设置浏览器访问的url地址
    </servlet-mapping>

        有servlet标签,就要对应有一个servlet-mapping标签。

        class内绑定servlet类,注意该类必须是一个servlet类。

        url-pattern栏中设置浏览器访问的url地址。如上图设置,最终访问的是 localhost:8080/hello

3.servlet类

        如何让自己写的类成为一个servlet?

public class HelloServlet extends HttpServlet

        只需要让我们的类继承HttpServlet类即可。

        该类中存在着许多方法,我使用时一般需要重写其中的doGet以及doPost方法,根据需求,这两者相互调用即可

4.servlet中context的使用

        4.1 传递数据

 编写一个HelloServlet类 

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   初始化Servlet配置
        //this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();

        String name="林志玲";//数据

        context.setAttribute("username",name);//将数据保存在了context中,名字为username,值为name

    }
}

        在servlet类中,通过this.getServletContext()可以获取Servlet的上下文context。

        context.setAttribute方法则起到了数据储存的功能。

我们如何在别的servlet中获取该数据呢?编写另一个类GetServlet

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取context上下文
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setCharacterEncoding("utf-8");//设置编码集防止乱码
        resp.setContentType("text/html");//告诉浏览器以文本形式展示

        PrintWriter writer = resp.getWriter();
        writer.print(username);//展示在浏览器界面
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

        首先通过this.getServletContext()获取上下文context。这里不同servlet类所获得的的context都会是同一个context。

        context.getAttribute方法则是取得之前所保存的数据。名称需要一致(username)。

        

在web.xml中注册这两个servlet

<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.leo.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.leo.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

        此时我们首先访问HelloServlet: localhost:8080/hello将数据(username:林志玲)存入

        在访问GetServlet:localhost:8080/getc 将(username:林志玲)获取并展示在网页:

        4.2 获取配置参数

我们可以在web.xml中为servlet配置一些参数:

<!--配置web初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>

同时也可以通过context将它们取得。

编写类:

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取context上下文
        ServletContext context = this.getServletContext();
        //获取配置中的信息
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

        依然先获取context对象。

        通过context.getInitParameter方法获取参数(url),打印在网页上。

注册servlet:

<servlet>
        <servlet-name>gp</servlet-name>
        <servlet-class>com.leo.servlet.ServletDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>gp</servlet-name>
        <url-pattern>/gp</url-pattern>
    </servlet-mapping>

访问: localhost:8080/gp

        4.3 转发页面

在我们访问一个页面的时候,通过转发功能,会跳转到另外一个指定的页面

编写类:

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取context上下文
        ServletContext context = this.getServletContext();
        System.out.println("进入Demo04");
        //获取转发器
        RequestDispatcher dispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
        dispatcher.forward(req,resp);//调用foreword方法进行转发
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

        context.getRequestDispatcher方法获取转发器,其参数就填你所要转发的路径,这里转发到上一个页面 localhost:8080/gp。

        dispatcher通过forward(req,resp)方法进行页面转发。

注册servlet:

<servlet>
        <servlet-name>sd4</servlet-name>
        <servlet-class>com.leo.servlet.ServletDemo04</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd4</servlet-name>
        <url-pattern>/sd4</url-pattern>
    </servlet-mapping>

首先尝试访问 localhost:8080/sd4 :

发现url地址栏仍然是我们访问的   localhost:8080/sd4 ,然而页面却跳转到了 localhost:8080/gp 的内容,这就是转发功能。

        4.4 获取配置文件以及其中的内容

通过context也是能够读取配置文件中的内容的,下面进行测试。

resources文件夹下创建一个配置文件db.properties:

username=root
password=123456

写一个servlet类:

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");//当前web下的路径
        Properties prop = new Properties();
        prop.load(is);
        resp.getWriter().print(prop.getProperty("username"));
        resp.getWriter().print(prop.getProperty("password"));

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

        通过流的形式把配置文件读取。

        getResourceAsStream()中的路径,不能直接填写"db.properties",必须填写其在web项目发布之后所存在的位置。寻找方法:

 在target文件夹下-->找到所发布的web项目-->WEB-INF-->classes-->db.properties。

注册servlet:

 <servlet>
        <servlet-name>sd5</servlet-name>
        <servlet-class>com.leo.servlet.ServletDemo05</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd5</servlet-name>
        <url-pattern>/sd5</url-pattern>
    </servlet-mapping>

访问:

         4.5 总结

        自定义的servlet类必须继承HttpServlet,这样才代表着此类是一个servlet。

        重写HttpServlet的doGet和doPost方法,两者可以互相调用。

        需要在web.xml中注册自定义servlet类。

        若要使用ServletContext中的功能,通过this.getServletContext,取得context对象,即可使用。

 

5.response的使用

        5.1 下载文件

将一个图片文件放到resources文件夹下

自定义servlet类:

public class FileServlet extends HttpServlet {
    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取下载文件的路径
        String realPath = "F:\\java\\idea\\javaweb\\response\\target\\response\\WEB-INF\\classes\\1.png";
        System.out.println("下载文件的路径"+realPath);
        //2.获取下载文件的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        //3.设置让浏览器支持下载我们的东西
        resp.setHeader("Content-disposition","attachment;filename"+fileName);
        //4.获取下载文件输入流
        FileInputStream is = new FileInputStream(realPath);
        //5.创建缓冲区
        byte[] bytes = new byte[1024];
        int len = 0;
        //6.获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
        //7.将OutputStream流写入buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
        while ((len = is.read(bytes))>0){
            os.write(bytes,0,len);
        }

        is.close();
        os.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

注册servlet:

<servlet>
    <servlet-name>down</servlet-name>
    <servlet-class>com.leo.servlet.FileServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>down</servlet-name>
    <url-pattern>/down</url-pattern>
  </servlet-mapping>

访问  localhost:8080/down  后即可下载该图片文件。

        5.2 自定义图片

编写servlet类

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //设置浏览器3秒钟刷新一次
        resp.setHeader("refresh","3");

        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();//笔
        //设置背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.blue);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);
        //告诉浏览器这是个图片,用图片的方式打开
        resp.setContentType("image/jpeg");
        //不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

        //把图片写给浏览器
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }

    //生成随机数
    public String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7-num.length(); i++) {
            sb.append("0");
        }
        num=sb.toString()+num;
        return num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

注册servlet

<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>com.leo.servlet.ImageServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/im</url-pattern>
  </servlet-mapping>

访问:

        5.3 重定向(重要)

前2个功能在应用场景不大,重定向功能则是resp十分重要的应用。

编写servlet类:

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/im");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

        resp的sendRedirect方法实现了重定向功能。方法的参数就填写你所要重定向到的页面。

注册servlet:

<servlet>
    <servlet-name>redirect</servlet-name>
    <servlet-class>com.leo.servlet.RedirectServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>redirect</servlet-name>
    <url-pattern>/red</url-pattern>
  </servlet-mapping>

访问 http://localhost:8080/red

         我们输入http://localhost:8080/red,访问到的地址却是im (80×20)。这就是重定向,地址栏会发生改变。

        5.5 总结

        response中最重要的应用是重定向,记住sendRedirect方法即可。

6.request的使用

        6.1 获取参数

通过req.getParameter()方法,可以获取请求中携带的参数。

编写index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>

<h1>
    登录
</h1>

<div style="text-align: center">
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        爱好:
        <input type="checkbox" name="hobby" value="女孩">女孩
        <input type="checkbox" name="hobby" value="代码">代码
        <input type="checkbox" name="hobby" value="电影">电影
        <input type="checkbox" name="hobby" value="运动">运动
        <br>
        <input type="submit">
    </form>

</div>

</body>
</html>

        这里我们通过表单的形式,能够上传我们所命名的属性:username、password、hobby

编写servlet:

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.setCharacterEncoding("utf-8");


        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");

        System.out.println("---------");
        System.out.println(username + "     " + password);
        System.out.println("---------");
        System.out.println(Arrays.toString(hobbies));

        //通过request转发
        req.getRequestDispatcher("/successful.jsp").forward(req,resp);
    }
}

        这里可以看到的是,我们使用了req.getParameter()方法,来获取上传到表单的参数,获取名字必须一致。

注册servlet:

 <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.leo.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
  

结果:

        访问了登录页面后,展示的是index.jsp的界面。我们填好内容,并且提交后:

 可以看到控制台确实获取到了我们的参数。

        6.2 转发      

转发是request中最常使用的方法,其功能是将此页面转发到另一页面,也是实现页面的跳转。

代码和6.1中一样。我们通过req.getRequest.Dispatcher("").forward(req,resp)的方法,实现了页面的转发。其中,第一个括号内要填的参数是你所要转发到的页面。

为了测试转发,在编辑一个successful.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>
    successful!
</h1>

</body>
</html>

结果:

        当我们点击提交后,跳转到了successful.jsp页面,完成了页面的转发。 

6.3 request转发和response重定向的区别

        相同点:都能实现页面的跳转

        不同点:

转发:

可见的URL地址栏并未发生改变,仍然是跳转前界面的地址

重定向:

如上面,访问的是http://localhost:8080/red,然而跳转到此页面时,顶部的URL地址栏也发生了变化。

更多异同参考其他文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值