【Servlet】 二

本文主要介绍了如何运用smart Tomcat与IDEA的结合方便地编写Servlet代码,以及Servlet API 

引言

前面我们介绍了编写Servlet程序的七个步骤,如下:

一旦有错误 , 如果需要修改代码,就需要重复上述567 ,比较麻烦...

于是有大佬想出来一个办法:让idea和tomcat集成起来,直接使用idea图形化界面把代码 部署到tomcat上,达成一键式是打包&部署过程

一.smart Tomcat插件

这个集成的工具就是smart Tomcat插件 , 在idea的插件市场中搜索下载即可 ! 

1.配置

首次对Servlet项目使用的时候,需要做一些配置

* 未配置的时候,显示的是configuration ,点击它

* 左侧选中Smart Tomcat 然后 + 

*第一个框出的地方选择tomcat的目录 ; 第二个框框就当于是之前打的war包的名字

2.常见错误分析

2.1.404

要访问的资源不存在

a.检查请求的路径

b.确认你的webapp是否被正确加载

多关注日志!

2.2 405

a.写的do**方法和请求发起的方法不匹配

  浏览器发GET请求,服务器代码写的是doPost

b.发的是GET请求,服务器代码写的也是doGet,

但是没有把super.doget删掉

在浏览器输入url,发起的就是get请求

2.3 500

服务器内部错误

代码中抛出异常

2.4 空白页面

返回的页面没有body,没有知道higetwriter.write()

2.5 无法访问此网站

服务器没有正确运行/ip,端口号编写错误


二.Servlet API

1.HttpServlet

编写Servlet代码用到的核心的类

通过继承这个类,并重写其中的方法,让tomcat去调用

init

在webapp被加载的时候执行

destroy

webapp被销毁的时候执行(不保证能够执行)

service

每次收到请求,都会执行,处理每个请求

doGet

收到Get请求的时候调用(由service方法调用)

doPost

收到Post请求的时候调用(由service方法调用)

doPut/doDelete/….

收到其他请求的时候调用(由service方法调用)

tomcat结束方式:

1.通过8005,给tomcat发起特殊请求(能够执行destroy)

2.直接杀死tomcat进程(无法执行到destroy)  (更多)

因此不能依赖destroy ! 

注意:

往往使用do**替代service

总的来说,前三个用的都不多,但是面试会考

面试题:

谈谈Servlet的生命周期. 

1.webapp刚被加载的时候,调用servlet的init方法

2.每次收到请求的时候,调用service方法

3.webapp要结束的时候,调用destroy方法

浏览器只能比较方便的构造get请求,不太方便构造其他的

针对其他的方法要构造,使用ajax或者postman

比如:

2.HttpServletRequest

Tomcat收到的http请求,就会被解析成这个对象

URI 唯一资源标识符

URL 唯一资源定位符

URL是URI的一种实现方式

Enumeration getParameterName()

返回一个String对象的枚举,把query string解析成map这样的键值对结构对

String getParameter(String name)

根据key获取到value

Enumeration getHeaderNames()

获取到请求头里面的键值对. tomcat将请求头解析成键值对

String getHeader(String name)

根据key获取到value

String getContentType()

获取body的类型

InputStream getInputStream()

读取这个流对象就能得到body内容

注意:

smart tomcat不是将webapp拷贝到webapps目录下,而是会创建一个另一个目录(临时目录)会让tomcat加载这个临时目录中的webapp

如何获取到query string 和 body

1.获取query string

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

@WebServlet("/parameter")
public class ParameterServlet extends HttpServlet {

    //约定客户端使用query string传递数据
    //query string :形如username=zhangsan&password=123
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username=req.getParameter("username");
        String password=req.getParameter("password");

        System.out.println("username"+username);
        System.out.println("password"+password);
        resp.getWriter().write("ok");
    }
}

2.获取body( 只考虑form表单的格式)

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

@WebServlet("/parameter2")
public class ParameterServlet2 extends HttpServlet {

    //预期让客户端发送一个post请求,同时使用form格式的数据,在body中传过来
    //body: username=zhangsan&password=123
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username=req.getParameter("username");
        String password=req.getParameter("password");

        System.out.println("username="+username);
        System.out.println("password="+password);
        resp.getWriter().write("ok");
    }
}

3.获取body( 考虑body为json格式)

json格式非常常见

Servlet自身不能对json数据进行解析,需要引入第三方库来解析这个body数据

我们使用jackson   --- 第三方库 ,通过maven中引入依赖

中央仓库搜索这个Jackson依赖并引入

使用:

ObjectMapper    把一个对象映射到JSON字符串 , 也可以把JSON字符串映射到对象

  * readValue方法  把json字符串解析成java对象

  • 第一个参数是一个流对象 , 表示json哪里来
  • 第二个参数指定对象的类型 (需要定义一个类,使得这个类的属性的名字/类型和json字符串匹配)

输入的是json字符串,得到的是一个user对象(把json字符串,映射成一个对象)

使用postman构造post请求

注意 : json的key一定是字符串类型 , 原则上可以不写,但是有些库/程序检查更严格,就必须加上""

readValue方法工作流程:

先把json字符串解析成键值对放到map中,再根据参数填入的类对象,通过反射api可以知道这个类对象有哪些属性,以及这些属性的名字和类型,一次把这里的每个属性都取出来,通过属性名字查询map的key,把匹配到的key的value就赋值给这个对象的属性

jackson会通过反射的方式,把User类里包含的public属性获取到,此时就可以根据反射得到这里的属性名字 , 去json解析出来键值对( key , value) 中进行匹配, 如果和key匹配到了,就把value设置到刚才的对象的属性中.

3.HttpServletResponse

和http响应数据是一致的

  • 状态码
  • header
  • body

这些属性都可以进行设置

对于do**方法来说,本身要做的事情就是根据请求计算响应

  • 请求对象,是tomcat收到请求之后,对http协议解析得到的对象
  • 响应对象,是tomcat创建的空的对象,我们把响应对象属性设置好(相当于是一个输出型参数)

setStatus(int )

设置状态码

setHeader(String name ,String value)

设置header,如果name已经存在,则覆盖旧的

addHeader(String name ,String value)

设置header,如果name已经存在,不覆盖旧的(header中就可能出现key相同的两个键值对)

setContentType(String)

设置发送给客户端的响应的内容类型

setCharacterEncoding(String)

设置发送给客户端的响应的字符编码

sendRedirect(Stirng)

用来设置重定向响应

比如:

设置refresh , 每过两秒刷新一次浏览器

设置重定向

浏览器看到302状态码和localtion就会跳转到后面的页面.

可以用下面这行代码代替上述两行代码

body

让服务器返回一个html数据

解决方法:使浏览器器用utf8编码

字符编码

一般在idea中直接写一个中文 , 使用的是utf8编码(可修改)

浏览器默认会跟随系统的编码  windows简体中文版默认编码是gbk

所以直接idea直接写中文,浏览器用gbk来解析会出现乱码

注意:

在servlet中,给resp设置属性的时候,注意顺序!   先设置header或设置body


以上就是三个核心的api的涉及到的类.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值