本文主要介绍了如何运用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的涉及到的类.