JAVAWEB学习(二)Servlet,Response验证码实现,重定向和Request

Servlet

1.1简介
Servlet就是sun公司开发动态web的一门技术
Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:

  • 编写一个类,实现Servlet接口
  • 把开发好的Java类部署到web服务器中。

把实现了Servlet接口的Java程序叫做,Servlet

1.2使用步骤

1).构建一个普通的Maven项目,删除其中的src目录,再在这个项目里面创建一个Module项目,这个空的module项目就是Maven的主工程,也可以将其看做父子工程,外面的Maven为父工程,里面的module为子工程,父项目中的java,子项目可以直接使用,父项目中导包后子项目不需要导包。

2).修改web.xml为最新的,将maven结构搭建完整

3).编写一个普通类,实现Servlet接口,也就是直接继承HttpServlet类

4).编写Servlet映射

我们写的java程序需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。

在web.xml文件中,通过以下代码创建映射

     <!--注册Servlet-->
<servlet>
        <servlet-name>这里是虚拟路径映射,由自己写</servlet-name>
        <servlet-class>这里是你写的java文件,格式为(包名.类名)</servlet-class>
 </servlet>
 
     <!--Servlet的请求路径-->
 <servlet-mapping>
        <servlet-name>和虚拟路径保持一致</servlet-name>
        <url-pattern>/和虚拟路径保持一致</url-pattern>
 </servlet-mapping>

5).配置Tomcat,配置项目发布的路径就可以了

6).启动

1.3 servlet的原理:

在这里插入图片描述

在这里插入图片描述
1.4 servlet的实现类:

servlet接口Sun公司定义了两个默认的实现类,GenericServlet,HttpServlet。
在这里插入图片描述

1.5 mapping问题

1.一个Servlet可以指定一个映射路径
<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
 </servlet-mapping>
 
    
2.一个Servlet可以指定多个映射路径
 <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>
    
3.一个Servlet可以指定通用映射路径
<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

4.默认请求路径
<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
</servlet-mapping>

5.指定一些后缀或者前缀等等
<!--可以自定义后缀实现请求映射
    注意点,*前面不能加项目映射的路径
    hello/sajdlkajda.qinjiang
    只要以.qinjiang结尾的
    -->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.qinjiang</url-pattern>
</servlet-mapping>

6.优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

1.6ServletContext

1)简介

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

2)共享数据

我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;

public class HelloServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        
       
        ServletContext context = this.getServletContext();

        String username = "aaa"; //数据
        context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username

    }

}
public class GetServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);

    }

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


  <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.kuang.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.kuang.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

//第一次通过hello执行存储username的操作,第二次通过getc执行获取username并将其输出的操作

3).利用ServletContext实现请求转发。

4).读取资源文件

​ 不管是在在java目录下新建properties,还是在resources目录下新建properties,我们发现都被打包到了同一个路径下:classes,我们俗称这个路径为classpath。我们需要一个文件流

username=root12312
password=zxczxczxc
public class ServletDemo05 extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.properties");

        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");

        resp.getWriter().print(user+":"+pwd);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req, resp);
    }
}
<servlet>
    <servlet-name>hello4</servlet-name>
    <servlet-class>kuang.servlet.ServletDemo05</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello4</servlet-name>
    <url-pattern>/hello4</url-pattern>
  </servlet-mapping>

Response验证码实现

2.1创建一个页面用于生成随机数

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

    }

    //生成随机数
    private 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-name>hello3</servlet-name>
    <servlet-class>Test1.ImageServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello3</servlet-name>
    <url-pattern>/hello3</url-pattern>
  </servlet-mapping>

//通过hello3跳转到一个可以生成随机数的页面

重定向

3.1 概念

一个web资源B收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向。

3.2举例


public class PageRedirect extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //方法一
        //设置相应内容类型
        resp.setContentType("text/html;charset=UTF-8");
        //要重定向的位置
        String site=new String("http://www.baidu.com");
        //resp.sendRedirect();
        resp.setStatus(resp.SC_MOVED_TEMPORARILY );
        resp.setHeader("location",site);
        
        //方法二
		 resp.sendRedirect("/r/img");
    }

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

<servlet>
  <servlet-name>helllo</servlet-name>
  <servlet-class>Test.PageRedirect</servlet-class>
</servlet>
  <servlet-mapping>
    <servlet-name>helllo</servlet-name>
    <url-pattern>/bb</url-pattern>
  </servlet-mapping>

3.3重定向和转发的区别

1)相同点
页面都会实现跳转
2)不同点
请求转发的时候,url不会产生变化 307
重定向时候,url地址栏会发生变化; 302

HttpServletRequest

4.1 概念

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;

4.2举例

package com.kuang.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class FormServlet1 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");
        //处理前端的请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println("接收到的用户名:"+username+"\n密码:"+password+"\n爱好:");

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

        for (String hobby : hobbies) {
    
    
            System.out.println(hobby);
        }


        //重定向:服务器告诉客户端你应该请求另外一个地址;  (地址栏会变)
        //resp.sendRedirect("url");

        //转发:服务器把这个请求转向另外一个Servlet去处理; (地址栏不会变)
        //RequestDispatcher ,需要使用RequestDispatcher来进行处理,我们需要获得这个类
        //参数就是他要转发到的页面

        /*
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/success.jsp");
        requestDispatcher.forward(req,resp);
        */

        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }

        req.getRequestDispatcher("/success.jsp").forward(req,resp);


    }
}

猜你喜欢

转载自blog.csdn.net/jingli456/article/details/113834164