目录
四、setCharacterEncoding和setContentType区别?
5.2 ObjectMapper类的writeValueAsString方法
八、对jquery方法中的success: function的理解
九、对JOSN.stringify()和JOSN.parse()的认识
| 方法名称 | 调用时机 | 作用及扩展解释 |
|---|---|---|
| init | 在HttpServlet实例化之后调用一次 | 作用:用来初始化; 扩展解释:首次访问的到时会实例化,创建出HttpServlet实力会调用一次; |
| destroy | 在HttpServlet实例不再使用时调用一次 | 作用:关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动; 扩展解释:他是通过8005端口控制Tomcat,来告诉Tomcat执行destroy;但是,不一定真的可以调用到,Tomcat关闭(杀进程:比如点击x,来关闭idea,或者拔电源...),则不调用HttpServlet; |
| service | 收到HTTP请求时调用 | 作用:通过Tomcat收到的请求来调用service,service根据请求中不同的方法,调用不同的doXXX; 扩展解释:实际开发中,很少重写service,一般重写doXXX就可以了; |
| doGet | 收到GET请求时调用 | 作用:根据请求计算响应 |
| doPost | 收到POST请求时调用 | 作用:根据请求计算响应 |
| doPut/doDelete/doOptions/... | 收到对应的请求时调用 | 作用:根据请求计算响应 |
什么是声明周期?
声明周期实际上就是,正确的时间干正确的事情;
回答:(根据以下,可以简略回答)
初始阶段,实例化的时候,会调用一次init;
每次收到请求,就会调用service,service根据请求中不同的方法,调用不同的doXXX;
结束销毁之前,调用destroy,用来关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动;
| 方法 | 描述 |
|---|---|
| String getProtocol() | 返回请求协议的名称和版本。 |
| String getMethod() | 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。 |
| String getRequestURI() | 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。 |
| String getContextPath() | 返回指示请求URL的一级路径 |
| String getQueryString() | 返回包含在路径后的请求 URL 中的查询字符串。 |
| Enumeration getHeaderNames() | 返回一个枚举,包含在该请求中包含的所有的头名。 |
| String getHeader(Stringname) | 以字符串形式返回指定的请求头的值。 |
- 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 showRequest extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //获取请求头
- Enumeration
headerName = req.getHeaderNames(); - while(headerName.hasMoreElements()) {
- String name = headerName.nextElement();
- String value = req.getHeader(name);
- stringBuilder.append(name + ":" + value);
- stringBuilder.append("
"); - }
- resp.setContentType("text/html");
- resp.getWriter().write(stringBuilder.toString());
- }
- }
HttpServletRequest的方法都是get系列,HttpServletResponse的方法都是set系列,doGet/doPost 这样的方法里的HttpServletResponse对象都是一个空对象;
| 方法 | 描述 |
|---|---|
| void setStatus(int sc) | 为该响应设置状态码。 |
| void setHeader(String name,String value) | 设置一个带有给定的名称和值的 header. 如果 name 已经存在, 则覆盖旧的值. |
| void addHeader(Stringname, String value) | 添加一个带有给定的名称和值的 header. 如果 name 已经存在, 不覆盖旧的值, 并列添加新的键值对 |
| void setContentType(Stringtype) | 设置被发送到客户端的响应的内容类型。 |
| void setCharacterEncoding(Stringcharset) | 设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。 |
| void sendRedirect(Stringlocation) | 使用指定的重定向位置 URL 发送临时重定向响应到客户端。 |
| PrintWriter getWriter() | 用于往 body 中写入文本格式数据. |
| OutputStream getOutputStream() | 用于往 body 中写入二进制格式数据. |
setCharacterEncoding只能设置字符编码;
setContentType不仅可以设置字符编码,还可以设置文档内容类型;
可以把json格式的数据转换成java的对象,第一个参数是可以是字符串也可以是输入流,第二个参数是类对象,是要解析出的结果的对象的类;
例如:(json格式的数据转换成java的对象)
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
-
- class Student {
- //1.所有属性必须要是公开的
- //2.必须要有无参的构造方法
- public int studentId;
- public int studentName;
- }
- public class Post extends HttpServlet {
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- ObjectMapper objectMapper = new ObjectMapper();
- Student s = objectMapper.readValue(req.getInputStream(), Student.class);
- //在服务器打印日志
- System.out.println(s.studentId);
- System.out.println(s.studentName);
- resp.setContentType("application/json; charset=utf8");
- //写入浏览器
- objectMapper.writeValue(resp.getWriter(), s);
- }
- }
可以把java的对象转换成json格式的数据;
例如:
- import com.fasterxml.jackson.databind.ObjectMapper;
-
- 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;
-
- class Student {
- //1.所有属性必须要是公开的
- //2.必须要有无参的构造方法
- public int studentId;
- public String studentName;
- }
- @WebServlet("/json")
- public class Post extends HttpServlet {
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- ObjectMapper objectMapper = new ObjectMapper();
- Student s = objectMapper.readValue(req.getInputStream(), Student.class);
- //在服务器打印日志
- System.out.println(s.studentId);
- System.out.println(s.studentName);
- resp.setContentType("application/json; charset=utf8");
- //写入浏览器
- resp.getWriter().write(objectMapper.writeValueAsString(s));
- }
- }
例如:(每隔一秒对页面进行刷新)
- 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("/autoRefresh")
- public class AutoRefresh extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- resp.setHeader("refresh", "1");
- resp.getWriter().write(System.currentTimeMillis() + " ");
- }
- }
解释:
header中的refresh属性,值是一个“秒数”,浏览器会在时间到了之后自动刷新;
虽然当前设置的时间是 1s 刷新一次,但是并不是精确的1000ms,会比1000ms略多一点,为什么呢?原因:调度要消耗时间、网络传输消耗时间、服务器响应、本身对ms级别的计时存在误差;
如下代码:(方法一:设置状态,再跳转;方法二:一步到位)
- 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 {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- //方法一:设置状态,进行跳转
- resp.setStatus(302);
- resp.setHeader("Location", "https://www.baidu.com");
- //方法二:一步到位
- resp.sendRedirect("https://www.baidu.com");
- }
- }
代码如下:
- $.ajax({
- type: 'post',
- url: 'message',//这里是相对路径
- data: JSON.stringify(data),//这里放的是body的内容
- contentType: "application/json; charset=utf8",
- success: function(body) {
- console.log("数据提交成功!");
- }
- });
解释和理解:
上述代码浏览器给服务器发送了一个带有数据data的post请求,随后服务器接收到了请求,如果服务器能正确的处理请求,则会调用浏览器的success方法,而body就是服务器请求后返回的信息,但如果没有正确处理请求,发生错误,就会不会调用success方法,而是会调用jquery的error方法;
以上,success就是一个回调函数,而浏览器用ajax请求服务器就是注册回调函数;
JOSN.stringify(参数):
JOSN.stringify()方法将一个 JavaScript 对象或值转换为 JSON 字符串,这就和 jackson 的writeValueAsString是一样的;
例如,如下代码:
- $('#d1').click(function(){ // button按钮触发点击事件
- $.ajax({
- url:'user',
- type:'post',
- data:JSON.stringify({'username':'jaychou','age':18}),//数据也需要转为JSON格式。
- contentType:'application/json; charset=utf8',//指定字符编码格式
- success:function (){
-
- }
- })
- })
JOSN.parse(参数):
JOSN.parse()方法是将 JSON 字符串成转换成 JavaScript的对象或值,这就和 jackson 的readValue是一样的;
如下代码
- function getMessages() {
- $.ajax({
- type: 'get',
- url: 'message',
- success: function(body) {//这里body由于jquery的特殊机制,已经转换成了数组
- //业务逻辑
- let container = document.querySelector('.container');
- for(let i = 0; i < body.length; i++) {
- let message = body[i];
- let div = document.createElement('div');
- div.className = 'row';
- div.innerHTML = message.from + ' 对 ' + message.to + ' 说: ' + message.message;
- container.appendChild(div);
- }
- }
- });
- }
解释:
以上代码,body是响应正文,本来是String类型,但是由于jquery的特殊机制,将body自动转换成了js的对象数组了,如果没有jquery做这件事情,就需要使用JSON.parse来完成;
