Servlet原理学习笔记(验证码、文件下载、重定向)

1.servlet原理图

在这里插入图片描述

  • 一、浏览器向Web容器发出HTTP请求。
  • 二、首次访问时,会向web.xml查询相应的路径。
  • 三、在web.xml中找到相映射的servlet类。
  • 四、HttpServlet的父类GenericServlet中有service方法的实现,这会将请求的类型分类处理,如GET、POST等。
  • 五、Web容器会将处理结果Response处理后返回到用户浏览器中。

2.Servlet映射配置

  • 在web.xml文件下配置Servlet

  • 将Servlet类映射到web访问路径

<!--Forexmaple
一个Servlet可以映射多个路径
-->
<servlet>
        <servlet-name>Thanks</servlet-name>
        <servlet-class>com.gu_ppy.servlet.HttpThanks</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Thanks</servlet-name>
        <url-pattern>/Thanks</url-pattern>
    </servlet-mapping>

3.默认映射路径

  • 此映射会在所有的访问路径下访问该Servlet
<servlet>
        <servlet-name>Thanks</servlet-name>
        <servlet-class>com.gu_ppy.servlet.HttpThanks</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Thanks</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

4.指定一些前缀或后缀(*为通配符)

   <servlet-mapping>
        <servlet-name>Thanks</servlet-name>
        <url-pattern>*.gu-ppy</url-pattern>
        <!--后缀为.gu-ppy-->
<!--*为通配符,可以匹配任何相似格式的请求,如果web.xml中有规定格式的则认为请求详细路径-->
    </servlet-mapping>
  • 有固有路径的映射就走,没有就走默认路径

4.ServletContext的作用

  • ServletContext:Servlet上下文,是为不同Servlet之间提供桥梁的工具,类似于Session

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qQRasM9R-1583916335251)(C:\Users\gu-ppy\AppData\Roaming\Typora\typora-user-images\image-20200217230853121.png)]

1.共享数据

  • 存放数据以及取数据
//存
context.setAttribute("name","Hello");
//取
Object name = context.getAttribute("name");

2.重定向与请求转发

请求转发代码:


this.getServletContext().getRequestDispatcher("/s1").forward(req,resp);
/**
*分组转发
*作用:请求转发,将请求转向另一个链接
*s1为目标链接
*/

重定向见下:重定向链接

  • 区别

请求转发在这里插入图片描述

3.读取资源文件

Properties文件

  • 在java目录下创建的 .properties文件
  • 在resoureces目录下创建的 .properties文件

它们在Build后,发现它们都在classes路径下,俗称classpath。

  • 可以使用ServletContext得到指向该配置文件的流,再新建一个Properties类以此来完成加载该配置文件。
ServletContext context = this.getServletContext();
//获取流
InputStream stream = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties pr = new Properties();
pr.load(stream);
String driver = pr.getProperty("driver");
String name = pr.getProperty("username");
String pass = pr.getProperty("password");

4.获取初始化web配置

  • 这是在web.xml中用于初始化web应用的配置代码(下方参数演示无实义)
<!--用于初始化web应用的配置-->
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/s</param-value>
</context-param>
  • 我们可以用ServletContext来获取web.xml中的自定义初始化配置信息

    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print("Url:"+url);
    

5.HttpServletResponse的使用

Web服务器收到用户从浏览器发出的Http请求后,它会针对这个请求创建两个部分,一个是HttpServletRequest另一个是HttpServletResponse

  • HttpServletRequest:包含用户请求的一些列信息
  • HttpServletResponse:包含将要返回给浏览器的信息

1.Response源码解析

  • Http请求以及响应分为两个部分
    • 请求体/响应体
    • 请求状态码/响应状态码
1、用于向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
2、响应头的操作的方法
  • 响应的头部操作
void setDateHeader(String var1, long var2);

void addDateHeader(String var1, long var2);

void setHeader(String var1, String var2);

void addHeader(String var1, String var2);

void setIntHeader(String var1, int var2);

void addIntHeader(String var1, int var2);
3、状态

​ Response和Request类似,都有自身的状态,代表在请求或者响应时的处理状态,在HttpServletResponse中有相应的状态常数,如下,

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;//一般为成功
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;//找不到资源
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;//服务端错误
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;//网关错误
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2.常见应用

1、向浏览器发送消息
  • 如常见的text/html文本

    resp.setContentType("text/html");
    resp.setCharacterEncoding("utf-8");
    ServletContext context = this.getServletContext();
    context.setAttribute("name","Hello");
    PrintWriter writer = resp.getWriter();
    writer.print("<html><head><title>Welcome</title></head><body><h1>欢迎进入Web世界</h1><hr/>Hello word</body></html>");
    
2、下载文件

要解决的问题:

​ 1.获取下载文件的路径是多少

​ 2.下载文件名是多少

​ 3.浏览器支持 & 获取输出流OutputStream

​ 4.获取下载文件的输入流

​ 5.创建缓冲区 & 发送文件

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //设置输入流读取文件
    String realPath = this.getServletContext().getRealPath("/resources/阅读.txt");
    System.out.println("路径:"+realPath);
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    System.out.println("文件名:"+fileName);
    FileInputStream in = new FileInputStream(realPath);

    //获取输出流并设置响应头信息,中文乱码使用的MimeUtility.encodeWord()来解决
    ServletOutputStream out = resp.getOutputStream();
    resp.setHeader("Content-Disposition","attachment;fileName="+ MimeUtility.encodeWord(fileName));
    //设置缓存区并发送
    int len=0;
    byte[] buffer = new byte[1024];
    while((len=in.read(buffer))>-1){
        out.write(buffer,0,len);
    }
    in.close();out.close();
}

**注意:**在ServletContext取得资源的路径中,资源尽量不要放到web根目录wbapp目录下和java目录下的reources文件夹下,它很有可能发生资源读取问题,最好自己在webapp下自建一个类似image、downlist、music等资源文件夹。

3、验证码

验证码在我们web应用中是一种很常见且对服务器减负的很有效的方法,这里用一个Servlet做一个小例子,并以此来学习Response。

  • 设置响应头信息
  • 创建image
  • 绘制image & 生成随机数
  • 发送image
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //告诉浏览器,5秒刷新一次
    resp.setHeader("refresh","8");
    //在内存中创建80x20的图片
    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("微软雅黑",Font.PLAIN,20));
    g.drawString(makeNum(),5,20);

    resp.setContentType("image/jpg");//设置文件信息

    resp.setHeader("expires","0");//缓存存在时间
    resp.setHeader("cache-control","no-cache");//缓存禁用上下三局
    resp.setHeader("pragma","no-cache");
 	//图片发送的方法,涨知识了
    ImageIO.write(image,"jpg",resp.getOutputStream());
}
  • 生成随机数字符串
/**
  *  生成随机数字符串
  * @return
  */
private String makeNum(){
    Random random = new Random();
    String num = random.nextInt(999999)+"";

    StringBuffer buffer = new StringBuffer();
    for(int i=0 ;i<6-num.length();i++){   //保证验证码总为6位
        buffer.append("0");
    }
    return buffer + num;
}
4、重定向

重定向:一个web服务器在收到一个请求后,它通知浏览器访问另外一个网址。

//接口
resp.sendRedirect("/web_01_war_exploded/s");

//解析
resp.setHeader("Location","/web_01_war_exploded/s");
resp.setStatus(302);

6.HttpServletRequest的使用

  • 用户通过http访问服务器,可以获取客户端的信息。

备注:

1.@Deprecated注解

  • 为建议不使用的方法或对象,可以用其他方法替代。
@Deprecated
String encodeRedirectUrl(String var1);

2.Response的setHeader()

1、一秒刷新页面一次

response.setHeader(“refresh”,1);

2、五秒跳到其他页面

response.setHeader("refresh","5;URL=otherPagename");

3、设置禁用缓存:

response.setHeader("expires", "0");
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");

4、设置过期的时间期限

response.setDateHeader("Expires",System.currentTimeMillis()+自己设置的时间期限);

5、访问别的页面:

response.setStatus(302; 
response.setHeader("location","url");

esponse.setHeader(“refresh”,“5;URL=otherPagename”);


3、设置禁用缓存:

```java
response.setHeader("expires", "0");
response.setHeader("cache-control", "no-cache");
response.setHeader("pragma", "no-cache");

4、设置过期的时间期限

response.setDateHeader("Expires",System.currentTimeMillis()+自己设置的时间期限);

5、访问别的页面:

response.setStatus(302; 
response.setHeader("location","url");
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值