Smart Tomcat + Servlet API的应用


前言

每一个项目都进行打包用起来过于的繁琐,为了更加便捷的使用,将Tomcat嵌入到idea中进行使用更加的方便,本篇文章记录了将Tomcat嵌入到idea中的方法以及为了更好的使用servlet介绍了servlet的API。


一、Smart Tomcat

上一篇文章讲述了安装Tomcat的过程,由于我使用的idea的社区版不能直接使用Tomcat,为了把Tomcat嵌入到idea中使用,于是通过在idea中下载插件Smart Tomcat,如下过程。
(1)打开idea,在左上角的File->Settings->Plugings->Marketplace中搜索Smart Tomcat进行安装。
在这里插入图片描述
在这里插入图片描述
(2)使用的时候就不需要再像上一篇文章介绍的手动打包项目到webapps下进行使用了,这里的Tomcat是针对当前.java进行使用的,所以所要在运行环境那个配置content-path,相当于你当时打包的包名。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

二、Servlet API

为了更好的了解以及使用servlet,这里详细记录了servlet的api。

1.HttpServlet

(1)方法

方法 描述
init 在HttpServlet实例化后被调用一次
destroy 在HttpServlet实例不再使用的时候调用一次
service 收到HTTP请求的时候调用
doGet 收到get请求的时候调用(service方法调用)
doPost 收到post请求的时候调用(service方法调用)
doPut/doDelete… 收到对应请求的时候调用(service方法调用)

(2)描述servlet的生命周期

第一步:当一个请求从HTTP服务器转发给servlet容器时,容器检查对应的servlet是否创建,没有创建就实例化该servlet,并调用init()方法,init()方法只调用一次,之后的请求都从第二步开始执行。
第二步:请求进入service()方法,根据请求类型转发给对应的方法处理,如doPost、doGet等等。
第三步:容器停止前,调用destroy()方法,进行清理操作,该方法只调用一次,随后JVM回收资源。

(3)案例

编写servlet代码,用来处理get、post、delete请求。
(1)使用ajax构造get、post、delete请求
代码如下(示例):

<body>
    <button onclick="sendGet()">发送get请求</button><br>
    <button onclick="sendPost()">发送post请求</button><br>
    <button onclick="sendDelete()">发送delete请求</button>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        function sendGet() {
    
    
            $.ajax({
    
    
                type: 'get',
                url: 'method',
                //请求成功后,将响应的内容打印在浏览器的控制台
                success: function(body) {
    
    
                    console.log(body);
                }
            });
        }
        function sendPost() {
    
    
            $.ajax({
    
    
                type: 'post',
                url: 'method',
                success: function(body) {
    
    
                    console.log(body);
                }
            });
        }
        function sendDelete() {
    
    
            $.ajax({
    
    
                type: 'delete',
                url: 'method',
                success: function(body) {
    
    
                    console.log(body);
                }
            });
        }
    </script>
</body>
</html>

(2)继承HttpServlet方法,直接重写doGet、doPost、doDelete方法。
代码如下(示例):

@WebServlet("/method")
public class ServletTest extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
    	//idea控制台打印
        System.out.println("get");
        //设置响应的字符类型,不设置可能会出现乱码
        resp.setContentType("text/html; charset=utf-8");
        //根据请求计算响应
        resp.getWriter().write("get 响应");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("post");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("post 响应");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("delete");
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().write("delete 响应");
    }
}

2.HttpServletRequest

(1)方法

方法 描述
String getProtocol() 返回请求协议的名称和版本
String getMethod() 返回HTTP方法的名称
String getRequestURL() 返回该请求的一部分(从协议名称一直到HTTP请求中的第一行的查询字符串)
String getContextPath() 返回指示请求上下文的请求URI部分(即URL中 IP:端口号 后面的一级目录部分)
String getQueryString() 返回URL中的查询字符串(querystring)
Enumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名
String getHeader(String name) 以字符串形式返回指定的请求头的值
Enumeration getParameterNames() 返回一个String类型的枚举,请求中包含的参数的名称
String getParameter(String name) 以字符串的形式返回请求参数的值,如果参数不存在则返回null
String[] getParameterValues(String name) 返回一个包含所有参数的值的字符串数组
String getCotentType() 返回请求主体的类型,不知道类型则返回null
int getCotentLength() 以字节为单位返回请求主体的长度,并提供输入流或长度未知时返回-1
InputStream getInputStream() 用于读取请求body内容,返回一个InputStream对象

(2)代码示例

打印请求信息

代码如下(示例):

@WebServlet("/showRequest")
public class ShowRequest extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //设置在浏览器中响应的格式,以防乱码
        resp.setContentType("text/html; charset=utf-8");
        //使用一个字符桶接收在req中得到的数据
        StringBuilder reqBody = new StringBuilder();

        //获取req的协议格式
        System.out.println(req.getProtocol());
        reqBody.append(req.getProtocol());
        reqBody.append("<br>");

        //获取req的请求方法
        System.out.println(req.getMethod());
        reqBody.append(req.getMethod());
        reqBody.append("<br>");

        //获取req的URI
        System.out.println(req.getRequestURI());
        reqBody.append(req.getRequestURI());
        reqBody.append("<br>");

        //获取req的content-path
        System.out.println(req.getContextPath());
        reqBody.append(req.getContextPath());
        reqBody.append("<br>");

        //获取req的queryString,没有则返回null
        System.out.println(req.getQueryString());
        reqBody.append(req.getQueryString());
        reqBody.append("<br>");

        reqBody.append("<h3>headers: </h3>");
        //获取req中的所有请求头名,是一个String对象的枚举类型
        Enumeration<String> enumeration =req.getHeaderNames();
        while (enumeration.hasMoreElements()) {
    
    
            //遍历枚举中的每个请求头名
            String headerName = enumeration.nextElement();
            reqBody.append(headerName + ": ");

            //根据请求头名得到请求头的值
            reqBody.append(req.getHeader(headerName));
            reqBody.append("<br>");
        }

        //将获取的信息写回响应
        resp.getWriter().write(reqBody.toString());
    }
}

获取get请求的参数

代码如下(示例):

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        resp.setContentType("text/html; charset=utf-8");
        String userId = req.getParameter("userId");
        String userName = req.getParameter("userName");
        resp.getWriter().write("userId= "+userId+"; "+"userName= "+userName);
    }
}

在这里插入图片描述

获取post请求的参数

方法一:body采用form表单格式

代码如下(示例):

构造form表单

<body>
    <form action="postParameter" method="post">
        <input type="text" name="userId">
        <input type="text" name="userName">
        <input type="submit" value="提交">
    </form>
</body>

服务器端代码

@WebServlet("/postParameter")
public class PostParameter extends HttpServlet {
    
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //设置请求解析时的编码类型
        req.setCharacterEncoding("utf-8");
        //设置响应时的编码格式和类型
        resp.setContentType("text/html; charset=utf-8");
        //根据参数名获取参数值
        String userId = req.getParameter("userId");
        String userName = req.getParameter("userName");
        System.out.println("userId= "+userId+"; "+"userName= "+userName);
        resp.getWriter().write("userId= "+userId+", "+"userName= "+userName);

        resp.getWriter().write("<br>"+"values:"+"<br>");
        //获取所有参数名
        Enumeration<String> enumeration = req.getParameterNames();
        while (enumeration.hasMoreElements()) {
    
    
            String names = enumeration.nextElement();
            //根据参数名获取参数值
            resp.getWriter().write(req.getParameter(names)+"<br>");
        }
    }
方法二:body采用JSON格式

代码如下(示例):
构造json.html页面

<body>
    <button onclick="sendJson()">以Json格式发送POST请求</button>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        function sendJson() {
    
    
            $.ajax({
    
    
                url: 'postParameterJson',
                type: 'post',
                contentType: 'application/json; charset=utf-8',
                success: function(body) {
    
    
                    console.log(body);
                }
            });
        }
    </script>
</body>

服务器端(PostParameterJson())

@WebServlet("/postParameterJson")
public class PostParameterJson extends HttpServlet {
    
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //设置请求解析时的字符类型
        req.setCharacterEncoding("utf-8");
        //设置响应格式和字符类型
        resp.setContentType("application/json; charset=utf-8");

        //获取req的body长度
        int contentLength = req.getContentLength();
        //构造长度为contentLength的字节数组
        //由于getContentLength是以字节为单位返回的请求长度,并提供输入流
        byte[] buffer = new byte[contentLength];
        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);

        System.out.println(new String(buffer));
        resp.getWriter().write(new String(buffer));
    }
}
postman下载安装及构造数据

其中JSON的数据可以通过postman构造:点击可到postman官网下载
下载注册后,按照以下形式选择构造:
在这里插入图片描述

方法三:引入Jackson库,进行JSON解析

(1)在MVN中获取Jackson的依赖。
在这里插入图片描述
选择其中一个版本的,这里是用的2.12.3
在这里插入图片描述
在这里插入图片描述
(2)引入依赖到pom.xml中
将如下图中的内容粘贴到pom.xml中,点击maven的刷新按钮,引入成功后不会报红。(可以根据上方在mvn中找到想要的版本进行引入,也可以直接粘贴如下代码)

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

在这里插入图片描述
(3)调用ObjectMapper中的方法

代码如下(示例):

class Course {
    
    
    public ArrayList<String> courses;
}
class Student {
    
    
    public String studentId;
    public String studentName;
    public Course course;
}
@WebServlet("/postParameterJackson")
public class PostParameterJackson extends HttpServlet {
    
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //创建ObjectMapper对象,它是Jackson中的核心类
        ObjectMapper objectMapper = new ObjectMapper();
        //1.调用ObjectMapper中的方法
        //readValue方法 将字符串转为对象;
        //writeValueAsString方法 将对象转为JSON格式字符串

        //读取输入流,获取到要解析的字符串
        //把字符串按照JSON格式解析,得到一组键值对(Map)
        //根据类对象,创建一个是咧
        //遍历类对象中的属性的名字,根据名字在Map中查询到value赋值到对应对象的属性中
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);

        System.out.println("id: "+student.studentId+", name:"+student.studentName+", "+student.course.courses);
//        resp.setContentType("text/html; charset=utf-8");
//        resp.getWriter().write(student.studentId+", "+student.studentName);
        resp.setContentType("application/json; charset=utf-8");
        resp.getWriter().write(objectMapper.writeValueAsString(student));
    }
}

3.HttpServletResponse

如下是servlet中响应(response)的一些主要方法。

(1)方法

方法 描述
void setStatus(int sc) 为该响应设置状态码
void setHeader(String name,String value) 设置一个给定名称和值的header,如果name已经存在,则覆盖
void setHeaders(String name,String value) 设置一个给定名称和值的header,如果name已经存在,不覆盖旧值,并添加新的键值对
void setContentType(String type) 设置被发送到客户端的响应的内容类型
void setCharacterEncoding(String charset) 设置发送到客户端的响应字符编码
void sendRedirect(String location) 使用指定的URL,发送临时重定向(302)到响应客户端
PrintWriter getWriter() 用于往body中写入文本格式数据
OutputStream getOutputStream() 用于往body中写入二进制格式数据

(2)代码示例

设置状态码

代码如下(示例):

@WebServlet("/status")
public class StatusServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
//        String status = req.getParameter("status");
//        if(status!=null) {
    
    
//            resp.setStatus(Integer.parseInt(status));
//        }
//        resp.getWriter().write("status: "+status);

        String type = req.getParameter("type");
        if(type.equals("1")) {
    
    
            resp.setStatus(200);
        }else if(type.equals("2")) {
    
    
            resp.setStatus(404);//浏览器自定义格式的404页面
            //resp.sendError(404);//sendError为Tomcat定义的404页面
        }else if(type.equals("3")){
    
    
            resp.setStatus(500);
        }else {
    
    
            resp.setStatus(502);
        }
    }
}

自动重刷线

代码如下(示例):

@WebServlet("/autoRefreshServlet")
public class AutoRefreshServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //设置响应格式
        resp.setContentType("text/html; charset=utf-8");
        //设置自动刷新时长
        resp.setHeader("refresh","1");
        //响应时间戳
        //resp.getWriter().write(System.currentTimeMillis()+"<br>");

        //获取日期类
        Date date = new Date();
        //将时间戳写入响应
        resp.getWriter().write("timeStamp: "+date.getTime()+"<br>");
        //通过SimpleDateFormat格式化日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //得到格式后的日期
        String time = simpleDateFormat.format(date.getTime());
        //将格式化后的日期写入响应
        resp.getWriter().write("date: "+time);
    }
}

重定向

代码如下(示例):

@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //方法一
        //resp.setStatus(302);
        //resp.setHeader("Location","https://blog.csdn.net/qq_45283185?spm=1011.2415.3001.5343");
        //方法二
        resp.sendRedirect("https://www.sogou.com");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45283185/article/details/127919686