怎么做套系网站,ui网页设计论文,洛阳网百姓呼声,贵州省兴义市建设局网站首页文章目录 写在前面Smart Tomcat 插件Servlet 中常见的API1. HttpServletinit 方法destroy 方法service 方法Servlet 的生命周期 使用 postman 构造请求使用 ajax 构造请求2. HttpServletRequest3. 前端给后端传参1). GET, query string2). POST, form3). json 4. HttpServletRe… 文章目录 写在前面Smart Tomcat 插件Servlet 中常见的API1. HttpServletinit 方法destroy 方法service 方法Servlet 的生命周期 使用 postman 构造请求使用 ajax 构造请求2. HttpServletRequest3. 前端给后端传参1). GET, query string2). POST, form3). json 4. HttpServletResponse 写在前面
上一篇我们写了第一个 Servlet 程序, 是使用 Servlet 最朴素的方式. 我们也可以通过一些操作来简化这些步骤.
这就不得不提到插件了 IDEA 功能非常强大吗, 但也不是面面俱到的, IEDA 提供了一些 API , 可以让程序员开发插件对 IDEA 现有的功能进行扩展. Smart Tomcat 插件 安装好重启 IDEA 即可
首次使用这个插件的时候, 我们需要配置一下.
新增一个运行配置 新增配置 设置一下 Tomcat 的位置, 其他的保持默认即可 运行 运行之后, idea 就会自己调用 Tomcat 执行了. 这样的话我们是不是就方便了许多呢, 就算我们修改数据之后也只需在 idea 中重启一下服务器即可, 就不需要手动打包部署了. smart tomcat 的工作原理 它不是把 war 包拷贝了(webapp 里没变), idea是通过另一种方式来启动 tomcat 的 tomcat 支持启动的时候显示指定一个特定的 webapp 目录, 相当于是让 tomcat 加载单个 webapp 运行. idea 直接调用 tomcat , 让 tomcat 加载当前项目中的目录. 这个过程其实没有打 war 包的过程, 也没有拷贝, 也没有解压缩的过程. Servlet 中常见的API
1. HttpServlet
我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法
方法名称调用时机init在 HttpServlet 实例化之后被调用一次destory在 HttpServlet 实例不再使用的时候调用一次service收到 HTTP 请求的时候调用doGet收到 GET 请求的时候调用(由 service 方法调用)doPost收到 POST 请求的时候调用(由 service 方法调用)doPut/doDelete/doOptions/…收到其他请求的时候调用(由 service 方法调用)
init 方法 然后我们重启服务器, 重新访问 我们多刷新几次 tomcat 收到了 /hello 这样路径的请求就会调用 hello_servlet_1 进行实例化(实例化只进行一次) 后续在收到 /hello 此时不必再进行实例化, 直接复用之前的 hello_servlet_1 即可
destroy 方法 然后关闭服务器 但是这里的 destroy 不一定被执行到
如果是通过 smart tomcat 的停止按钮, 这个操作本质上是通过 tomcat 的 8005 端口, 主动停止, 能够触发 destroy.如果是直接杀进程, 此时可能来不及执行 destroy 就关闭了.
因此不太推荐使用 destroy, 不靠谱
service 方法
Servlet 的生命周期
开始的时候, 执行 init每次收到请求, 执行 service销毁之前, 执行 destroy 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(/method)
public class MethodServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(doGet);resp.getWriter().write(doGet);}Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(doPost);resp.getWriter().write(doPost);}Overrideprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(doPut);resp.getWriter().write(doPut);}Overrideprotected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(doDelete);resp.getWriter().write(doDelete);}
}根据不同的请求, 返回不同的响应
使用 postman 构造请求 使用 ajax 构造请求
首先创建一个 html 文件, 一定注意文件位置在 webapp 目录下
引入 jQuery cdn 链接, 编写代码
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
body!-- 使用这个页面来构造 ajax 请求--script srchttps://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js/scriptscript$.ajax({type:get,// 相对路径// url:method,// 绝对路径url:/test2/mothod,success: function(body, status) {console.log(body);}})/script
/body
/html这里的 url 是个相对路径, 相对路径的基准目录就是该 html 所在的路径
然后重新启动服务器, 重新访问
改这里的 type 类型就能构造出不同的请求
2. HttpServletRequest
核心方法
方法描述String getProtocol()返回请求协议的名称和版本String getMethod()返回请求的 HTTP 方法的名称例如GET、POST 或 PUTString getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中返回该请求的 URL 的一部分。String getContextPath()返回指示请求上下文的请求 URI 部分。String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。EnumerationgetParameterNames()返回一个 String 对象的枚举包含在该请求中包含的参数的名称。String getParameter(Stringname)以字符串形式返回请求参数的值或者如果参数不存在则返回null。String[] getParameterValues(Stringname)返回一个字符串对象的数组包含所有给定的请求参数的值如果参数不存在则返回 null。Enumeration getHeaderNames()返回一个枚举包含在该请求中包含的所有的头名。String getHeader(Stringname)以字符串形式返回指定的请求头的值。String getCharacterEncoding()返回请求主体中使用的字符编码的名称。String getContentType()返回请求主体的 MIME 类型如果不知道类型则返回 null。int getContentLength()以字节为单位返回请求主体的长度并提供输入流或者如果长度未知则返回 -1。InputStream getInputStream()用于读取请求的 body 内容. 返回一个 InputStream 对象. 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;
import java.util.Enumeration;WebServlet(/showRequest)
public class ShowRequestServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 这里设置 content-typeresp.setContentType(text/html);// 搞个StringBuild , 把这些的 api 的结果拼起来, 统一写回到响应中StringBuilder stringBuilder new StringBuilder();stringBuilder.append(req.getProtocol());stringBuilder.append(br);stringBuilder.append(req.getMethod());stringBuilder.append(br);stringBuilder.append(req.getRequestURI());stringBuilder.append(br);stringBuilder.append(req.getContextPath());stringBuilder.append(br);stringBuilder.append(req.getQueryString());stringBuilder.append(br);stringBuilder.append(br);stringBuilder.append(br);stringBuilder.append(br);stringBuilder.append(br);// 获取 header 中的键值对EnumerationString headerNames req.getHeaderNames();while (headerNames.hasMoreElements()) {String headerName headerNames.nextElement();stringBuilder.append(headerName : req.getHeader(headerName));stringBuilder.append(br);}resp.getWriter().write(stringBuilder.toString());}
} 3. 前端给后端传参
1). GET, query string
在前端给后端传练个数字, 一个是同学的 studentiId, 一个是 classId
?studentIt10classId20
下面编写代码来处理这个请求
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(/getParameter)
public class GetParameterServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 预期浏览器会发一个 /getParameter?studentId10classId20 请求// 借助 req 里的 getParameter 方法就能拿到 query string 中的键值对了.// getParameter 得到的是 String 类型的结果.String studentId req.getParameter(studentId);String classId req.getParameter(classId);resp.setContentType(text.html);resp.getWriter().write(studentId studentId class classId);}
}2). POST, form
对于前端是 form 表单这样格式的数据, 后端还是使用 getParameter 来获取. form 表单 这种格式也是键值对, 和 query string 的格式一样 只是这部分内容存在 body 中 下面我们编写代码
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/title
/head
bodyform actionpostParameter methodpostinput typetext namestudentIdinput typetext nameclassIdinput typesubmit value提交/form/body
/html输入内容提交就能构造出一个 POST 请求, 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(/postParameter)
public class PostParameterServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String studentId req.getParameter(studentId);String classId req.getParameter(classId);resp.setContentType(text.html );resp.getWriter().write(studentId: studentId class classId);}
}使用 getParameter 方法, 既可以获取到 query string 中的键值对, 也可以获取到 form 表单构造的 body 中的键值对.
3). json
json 也是一种非常主流的数据格式, 也是键值对结构. 我们可以把 body 部分 按照这个格式来组织 前端可以使用 ajax 的方式来构造出这个内容. 还可以用 postman 直接构造 编写代码
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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;/*** author chenhongfei* version 1.0* describe* date 2023/11/14*/
WebServlet(/postParameter2)
public class PostParameter2Servlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 通过这个方法来处理 body 为 json 格式的值// 直接把 req 对象里 body 完整读取出来// getInputStream// 在流对象中读多少个字节, 取决于 Content-Lengthint length req.getContentLength();byte[] buffer new byte[length];InputStream inputStream req.getInputStream();inputStream.read(buffer);// 把这个字节数组构造成 StringString body new String(buffer,0,length,UTF8);System.out.println(body body);resp.getWriter().write(body);}
}服务器这边我们也能看到 图解:
这个代码的执行流程, 和上个通过 form 表单传参, 流程是类似的. 只不过是传输的数据类型不同罢了.
form 表单是形如 classId20studentId10
json 的格式形如: { classId:20, studentId:10 } 本质上来说, 这三种方式都是等价的.
当前通过 json 传递数据, 但是服务器这边只是把整个 body 读出来, 还没有按照键值对的方式来处理(不能根据 key 获取 value) form 表单是可以根据 key 获取 value (getParameter 就支持了).
这里我们推荐使用第三方库, Jackson
通过 Meven 引入第三方库 meven 库 把代码复制到 pom.xml 编写代码 Student student objectMapper.readValue(req.getInputStream(),Student.class); 这个代码会从 body 中取出 json 格式的字符串 { classId: 20, studentId 10 }根据第二个参数类对象, 创建 Student 对象解析上述 json 的字符串, 处理成 map 键值对结构遍历所有键值对, 看键的名字和 Student 实例的哪个属性名字匹配, 就把对应的属性 value 设置到该属性中返回该 Student 实例 4. HttpServletResponse
Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到HttpServletResponse 对象中. 然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通过Socket 写回给浏览器
核心方法
方法描述void setStatus(int sc)为该响应设置状态码。void setHeader(String name,String value)设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值.void addHeader(Stringname, String value)添加一个带有给定的名称和值的 header. 如果 name 已经存在,不覆盖旧的值, 并列添加新的键值对void setContentType(Stringtype)设置被发送到客户端的响应的内容类型。void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码MIME 字符集例如UTF-8。void sendRedirect(String location)使用指定的重定向位置 URL 发送临时重定向响应到客户端。PrintWriter getWriter()用于往 body 中写入文本格式数据.OutputStream getOutputStream()用于往 body 中写入二进制格式数据.
设置字符编码
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(/getParameter)
public class GetParameterServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 预期浏览器会发一个 /getParameter?studentId10classId20 请求// 借助 req 里的 getParameter 方法就能拿到 query string 中的键值对了.// getParameter 得到的是 String 类型的结果.String studentId req.getParameter(studentId);String classId req.getParameter(classId);// 设置字符集, 中文不乱码resp.setContentType(text/html;charsetutf8);// resp.setCharacterEncoding(utf-8);resp.getWriter().write(学生 studentId 班级 classId);}
}重定向
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(/redirect)
public class RedirectServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect(https://www.sogou.com);}
}点击就跳转到了搜狗了 单独设置也可以 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//resp.sendRedirect(https://www.sogou.com);resp.setStatus(302);resp.setHeader(Location,https://www.sogou.com);}