Servlet的详细使用(上)

简介: Servlet的详细使用(上)



Servlet体系结构


我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会继承HttpServlet

@WebServlet("/demo4")
    public class ServletDemo2 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("get......");
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("post......");
        }
    }

运行之后我们访问请求路径,从代码可以看出我们这个Servlet里面有两个方法,一个doGet()和doPost()方法,当我们直接输入访问路径,默认的是执行get方法


运行结果:



对于post请求来说,我们得写一个表单来请求当前Servlet资源



运行结果:

1)页面跳转


2)


HttpServlet中为什么要根据请求方式的不同,调用不同方法?
post和get请求参数的位置不一样,post请求参数的位置在请求体里面,get请求参数在请求行里面,当我们继承Servlet接口里面,需要根据请求的方式不同,来进行分别的处理,需要在service方法里面先获取请求方式




Servlet urlPattern配置

Servlet想要被访问,必须配置其访问路径(urlPattern)

1.一个Servlet,可以配置多个urlPattern

WebServlet(urlPatterns = {"/demo4","/demo5"})
    public class ServletDemo4 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("demo4 get......");
        }
    }

2.urlPattern配置规则

1)精确匹配


2)目录匹配


注意:当一个路径同时满足精确匹配和目录匹配的时候,精确匹配的优先级大于目录匹配*

3)扩展名匹配


4)任意匹配


/*的优先级高于/

/和/的区别
当我们项目中的Servlet配置了“/”会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet
当我们的项目中配置了“/”,意味着匹配任意访问路径
配置任意访问路径会导致我们的任意访问资源无法使用,所以一般不要去配置它
优先级:精确路径>目录路径>扩展名路径>/>/


Request和Response介绍

Request:获取请求数据
Response:设置响应数据

示例代码:

@WebServlet("/demo2")
    public class ServletDemo2 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("get......");
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //使用request对象,获取请求数据
            String name = req.getParameter("name");
            //使用response对象,设置响应数据
            resp.setHeader("content-type","text/html;charaset=utf-8");
            resp.getWriter().write("<h1>"+name+",欢迎您!</h1>");
            System.out.println("post......");
        }
    }

Request

Request继承体系



Request获取请求数据

请求数据分为3部分:

1.请求行:


2.请求体:


字符输入流:一般用于文本的情况下
字节输入流:一般用于文件和图片的情况下

示例代码:

第一步:创建表单

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>
    <form action="/req1" method="post">
      <input type="text" name="username">
      <input type="password" name="password">
      <input type="submit">
    </form>
  </body>
</html>

第二步:编写dopost请求

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取post 请求体:请求参数
        //1.获取字符输入流
        BufferedReader br = req.getReader();
        //2.读取数据
        String line = br.readLine();
        System.out.println(line);
    }

运行结果:

3.请求头:



Request通用方式获取请求参数

GET请求方式和POST请求方式 区别主要在于获取请求参数的方式不一样,可以提供一种获取请求参数的方式,从而同一doGet和doPost方法
假设我们现在按原来的方法接收到了数据,但是数据时一条长长的字符串,我们还要拆分,这样是不是,有些麻烦


于是request就很贴心的为我们提供了一种方法


示例代码:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求限制
        System.out.println("get....");
        //1.获取所有参数的Map集合
        Map<String,String[]> map = req.getParameterMap();
        for(String key:map.keySet()){
            System.out.print(key+":");
            //获取值
            String[] values = map.get(key);
            for (String value:values){
                System.out.print(value+" ");
            }
            System.out.println();
        }
        //根据key获取参数值,数组
        String[] hobbies = req.getParameterValues("hobby");
        for(String hobby:hobbies){
            System.out.println(hobby);
        }
        //根据key,获取单个参数值
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }

同样的方法也能在doPost里面,我们完全可以在post请求里面填写一句this.doGet(req,resp);

请求参数中文乱码–post解决方案

当我们从表单post发送请求提交表单后的时候,request接收数据会乱码


(tomcat8及以后的版本,get方式不会乱码,post方式会乱码)
原因:post底层是通过getReader获取一个字符输入流,通过流的方式读取信息,该流的编码形式不是utf-8,但页面是utf-8的
解决方案:在请求里设置字符输入流的编码为UTF-8



请求参数中文乱码–get解决方案

get请求方式乱码不能用post乱码方式解决
乱码原因:
编码和解码不一致
拿一个代码举例

public class URLDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String username = "张三";
        //1.URL编码
        String encode = URLEncoder.encode(username, "utf-8");
        System.out.println(encode);
        //URL解码
        String decode = URLDecoder.decode(encode,"gbk");
        System.out.println(decode);
    }
}

运行结果:

*

由此可以看出因为编码和解码的不一致,导致我们运行结果不是我们想看到的

解决办法:

因为tomcat底层的方法是写死的,我们没有办法改变,但是我们可以想到它两个数据间的字节是一样的(二进制),我们可以把乱码数据转成二进制数据,再把二进制字节数据变成我们想要的数据*

public class URLDemo {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String username = "张三";
        //1.URL编码
        String encode = URLEncoder.encode(username, "utf-8");
        System.out.println(encode);
        //URL解码
        String decode = URLDecoder.decode(encode,"ISO-8859-1");
        System.out.println(decode);
        //3.转为字节数据
        byte[] bytes = decode.getBytes("ISO-8859-1");
        for(byte b:bytes){
            System.out.print(b+" ");
        }
        System.out.println();
        //4.将字节数组转为字符串
        String s = new String(bytes, "utf-8");
        System.out.println(s);
    }
}

运行结果:



目录
相关文章
|
10月前
|
XML Java 应用服务中间件
Servlet详解(上)
Servlet详解
66 0
|
3月前
|
JSON Java 应用服务中间件
|
3月前
|
XML 前端开发 Java
servlet使用
servlet使用
|
9月前
|
IDE Java 应用服务中间件
Servlet3.0
Servlet3.0
|
3月前
|
Oracle Java 关系型数据库
浅谈Servlet
浅谈Servlet
17 0
|
应用服务中间件
Servlet2(2)
Servlet2(2)
58 0
|
10月前
|
JSON 前端开发 Java
Servlet详解(下)
Servlet详解
62 0
|
12月前
|
XML JavaScript 前端开发
servlet详解
servlet详解
|
小程序 Java 应用服务中间件
Servlet1(1)
Servlet1(1)
67 0
Servlet(三)
关于Servlet的相关介绍
130 0
Servlet(三)