文章目录
- 前言
- 一、Smart Tomcat
- 二、Servlet API
- 1.HttpServlet
- (1)方法
- (2)描述servlet的生命周期
- (3)案例
- 2.HttpServletRequest
- (1)方法
- (2)代码示例
- 打印请求信息
- 获取get请求的参数
- 获取post请求的参数
- 方法一:body采用form表单格式
- 方法二:body采用JSON格式
- postman下载安装及构造数据
- 方法三:引入Jackson库,进行JSON解析
- 3.HttpServletResponse
- (1)方法
- (2)代码示例
- 设置状态码
- 自动重刷线
- 重定向
前言
每一个项目都进行打包用起来过于的繁琐,为了更加便捷的使用,将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");
}
}