Servlet基础入门

2022-08-01 09:44:29 浏览数 (1)

Servlet

Servlet 是 Server Applet 的简称,译为“服务器端小程序”。Servlet 是 Java 的一套技术标准,规定了如何使用 Java 来开发动态网站。

  • Servlet 是 JavaEE 规范之一。规范就是接口
  • Servlet 就 JavaWeb 三大组件之一(三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器)。
  • Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

Servlet 应用程序的体系结构:

Servlet 的请求首先会被 HTTP 服务器(如 Apache)接收,HTTP 服务器只负责静态 HTML 页面的解析,而 Servlet 的请求会转交给 Servlet 容器,Servlet 容器会根据 web.xml 文件中的映射关系,调用相应的 Servlet,Servlet 再将处理的结果返回给 Servlet 容器,并通过 HTTP 服务器将响应传输给客户端。

Servlet 的生命周期

1、执行 Servlet 构造器方法

2、执行 init 初始化方法,在第一次访问的时候,创建 Servlet 程序会调用。

3、执行 service 方法,每次访问都会调用。

4、执行 destroy 销毁方法,在web 工程停止的时候调用

Http协议

客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫 HTTP 协议。

HTTP 协议中的数据又叫报文。 b)请求的 HTTP 协

HTTP 协议格式

GET 请求
  1. 请求行
    • 请求的方式 GET
    • 请求的资源路径[ ? 请求参数]
    • 请求的协议的版本号 HTTP/1.1
  2. 请求头

key : value 组成 (不同的键值对,表示不同的含义)

POST 请求
  1. 请求行
    • 请求的方式 POST
    • 请求的资源路径[ ? 请求参数]
    • 请求的协议的版本号 HTTP/1.1
  2. 请求头
    • key : value (不同的请求头,有不同的含义)
  3. 请求体(就是发送给服务器的数据)

常用请求头

Accept: 表示客户端可以接收的数据类型 Accpet-Languege: 表示客户端可以接收的语言类型 User-Agent: 表示客户端浏览器的信息 Host: 表示请求时的服务器 ip 和端口号

常见的GET 请求

  1. form 标签 method=get
  2. a 标签
  3. link 标签引入 css
  4. Script 标签引入 js 文件
  5. img 标签引入图片
  6. iframe 引入 html 页面
  7. 在浏览器地址栏中输入地址后敲回车

常见的POST 请求

  1. form 标签 method=post

响应的 HTTP 协议格式

  1. 响应行
    • 响应的协议和版本号
    • 响应状态码
    • 响应状态描述符
  2. 响应头
    • key : value (不同的响应头,有其不同含义)
  3. 响应体(即回传给客户端的数据)

参考图片见上图

常用的响应码

200 表示请求成功

302 表示请求重定向

404 表示请求服务器已经收到了,但是请求的数据不存在(请求地址错误)

500 表示服务器已经收到请求,但是服务器内部错误(代码错误)

Cookie

  1. Cookie 翻译过来是饼干的意思。2.
  2. Cookie 是服务器通知客户端保存键值对的一种技术。
  3. 客户端有了 Cookie 后,每次请求都发送给服务器。
  4. 每个 Cookie 的大小不能超过 4k

创建 Cookie

示例:

代码语言:javascript复制
  protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
          IOException {
//1 创建 Cookie 对象
      Cookie cookie = new Cookie("key4", "value4");
//2 通知客户端保存 Cookie
      resp.addCookie(cookie);
//1 创建 Cookie 对象
      Cookie cookie1 = new Cookie("key5", "value5");
//2 通知客户端保存 Cookie
      resp.addCookie(cookie1);
      resp.getWriter().write("Cookie 创建成功");
  }

获取 Cookie

代码语言:javascript复制
public class CookieUtils {
    /**
     * 查找指定名称的 Cookie 对象
     *
     * @param name
     * @param cookies
     * @return
     */
    public static Cookie findCookie(String name, Cookie[] cookies) {
        if (name == null || cookies == null || cookies.length == 0) {
            return null;
        }
        for (Cookie cookie : cookies) {
            if (name.equals(cookie.getName())) {
                return cookie;
            }
        }
        return null;
    }
}
代码语言:javascript复制
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
			// getName 方法返回 Cookie 的 key(名)
			// getValue 方法返回 Cookie 的 value 值
            resp.getWriter().write("Cookie["   cookie.getName()   "="   cookie.getValue()   "] <br/>");
        }
        Cookie iWantCookie = CookieUtils.findCookie("key1", cookies);
// for (Cookie cookie : cookies) {
// if ("key2".equals(cookie.getName())) {
// iWantCookie = cookie;
// break;
// }
// }
// 如果不等于 null,说明赋过值,也就是找到了需要的 Cookie
        if (iWantCookie != null) {
            resp.getWriter().write("找到了需要的 Cookie");
        }
    }

修改Cookie

方法一:

代码语言:javascript复制
// 1、先创建一个要修改的同名(指的就是 key)的 Cookie 对象
// 2、在构造器,同时赋于新的 Cookie 值。
Cookie cookie = new Cookie("key1","newValue1");
// 3、调用 response.addCookie( Cookie ); 通知 客户端 保存修改
resp.addCookie(cookie);

方法二:

代码语言:javascript复制
// 1、先查找到需要修改的 Cookie 对象
Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
if (cookie != null) {
	// 2、调用 setValue()方法赋于新的 Cookie 值。
	cookie.setValue("newValue2");
	// 3、调用 response.addCookie()通知客户端保存修改
	resp.addCookie(cookie);
}

Cookie生命周期控制

Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)

setMaxAge()

正数:表示在指定的秒数后过期

负数:表示浏览器关闭时,Cookie 就会被删除(默认值是-1)

零:表示马上删除 Cooki

示例:

代码语言:javascript复制
  /**
   * 设置存活 1 个小时的 Cooie
   * @param req
   * @param resp
   * @throws ServletException
   * @throws IOException
   */
  protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
          IOException {
      Cookie cookie = new Cookie("life3600", "life3600");
      cookie.setMaxAge(60 * 60); // 设置 Cookie 一小时之后被删除。无效
      resp.addCookie(cookie);
      resp.getWriter().write("已经创建了一个存活一小时的 Cookie");
  }
  /**
   * 马上删除一个 Cookie
   * @param req
   * @param resp
   * @throws ServletException
   * @throws IOException
   */
  protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
          IOException {
// 先找到你要删除的 Cookie 对象
      Cookie cookie = CookieUtils.findCookie("key4", req.getCookies());
      if (cookie != null) {
	// 调用 setMaxAge(0);
          cookie.setMaxAge(0); // 表示马上删除,都不需要等待浏览器关闭
	// 调用 response.addCookie(cookie);
          resp.addCookie(cookie);
          resp.getWriter().write("key4 的 Cookie 已经被删除");
      }
  }
  /**
   * 默认的会话级别的 Cookie
   * @param req
   * @param resp
   * @throws ServletException
   * @throws IOException
   */
  protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
          IOException {
      Cookie cookie = new Cookie("defalutLife","defaultLife");
      cookie.setMaxAge(-1);//设置存活时间
      resp.addCookie(cookie);
  }

Cookie 有效路径的设置

Cookie 的 path 属性可以有效的选择当前Cookie请求是否发送给服务器的 path 属性是通过请求的地址来进行有效的过滤。

CookieA path=/工程路径 CookieB path=/工程路径/abc

请求地址如下: http://ip:port/工程路径/a.html CookieA 发送 CookieB 不会发送

http://ip:port/工程路径/abc/a.html CookieA 发送 CookieB 发送

示例:

代码语言:javascript复制
protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
	Cookie cookie = new Cookie("path1", "path1");
	// getContextPath() ===>>>> 得到工程路径
	cookie.setPath( req.getContextPath()   "/abc" ); // ===>>>> /工程路径/abc
	resp.addCookie(cookie);
	resp.getWriter().write("创建了一个带有 Path 路径的 Cookie");
}

Session

服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。

Session用于存储一次会话的多次请求的数据(可以存储任意类型,任意大小的数据),存在服务器端

Session与Cookie的区别:

  1. Session存储数据在服务器端,Cookie在客户端
  2. Session没有数据大小限制,Cookie有
  3. Session数据安全,Cookie相对于不安全
代码语言:javascript复制
/**
* 向 Session 域中储存数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
	req.getSession().setAttribute("key1", "value1");
	resp.getWriter().write("数据已储存至 Session 中");
}
/**
* 获取 Session 域中的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
	Object attribute = req.getSession().getAttribute("key1");
	resp.getWriter().write("从 Session 中获取出 key1 的数据是:"   attribute);
}

Session生命周期

设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁:

setMaxInactiveInterval(int interval)

值为正数的时候,设定 Session 的超时时长。

负数表示永不超时(极少使用)

代码语言:javascript复制
protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
	// 先获取 Session 对象
	HttpSession session = req.getSession();
	// 设置当前 Session3 秒后超时
	session.setMaxInactiveInterval(3);
    
    // 让 Session 会话马上超时
	//session.invalidate();
    // 获取 Session 的超时时间
    //session.getMaxInactiveInterval();
    
	resp.getWriter().write("当前 Session 已经设置为 3 秒后超时");
}

AJAX

AJAX 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是一种创建交互式网页应用的网页开发技术。

AJAX 是一种浏览器异步发起请求,局部更新页面的技术(可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如搜索联想,在百度搜索框只输入一两个字搜索框下面就会自动列出可能搜索的关键词;或者是输入框校验,实时校验当前输入框是否符合输入规则;等等。。。。)。

AJAX可以与服务器数据进行交换,通过AJAX可以给服务器发送请求,并获取服务器响应的数据。

同步与异步

基本格式

代码语言:javascript复制
function ajaxRequest() {
    // 1、创建 XMLHttpRequest
    var xhr = new XMLHttpRequest();
    // 2、调用 open 方法设置请求参数
    // xhr.open(method, url, async); method:请求的类型,Get/Post;url:服务器(文件)位置;asyns:true(异步)、false(同步)
    xhr.open("GET", "ajaxServlet?action=javaScriptAjax&username="   new Date(), true);
    // 4、在 send 方法前绑定 onreadystatechange 事件,获取服务器响应数据,处理请求完成后的操作。
    xhr.onreadystatechange = function () {
        // 判断请求完成,并且成功
        if (xhr.readyState == 4 && xhr.status == 200) {
            document.getElementById("div01").innerHTML = xhr.responseText;
            //document.getElementById("div01").innerHTML = this.responseText;
            //alert(this.responseText);
        }
    }
    // 3、调用 send 方法发送请求(get)
    xhr.send();
    //Post
    //xhr.send(string);
}
代码语言:javascript复制
public class AjaxServlet extends BaseServlet {

  private static final long serialVersionUID = 1L;

  protected void javaScriptAjax(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    System.out.println("ajax 请求:"   request.getParameter("username"));
    // response.getWrite().write("ouo");
    Random random = new Random(System.currentTimeMillis());
    // 使用随机数,可以让客户端看到变化
    response.getWriter().write(new Gson().toJson(new GsonTest.Person(random.nextInt(100), "999")));
  }
}

获取JSON数据

实例:

代码语言:javascript复制
<html>  
<head>  
<meta content="text/html; charset=utf-8">  
<title>AJAX JSON</title>  
<script type="application/javascript">  
function load()  
{  
   var url = "http://127.0.0.1:8080/jsonValue";//传递JSON数据的地址
   var request;  
  
   if(window.XMLHttpRequest){    
    request=new XMLHttpRequest();//非IE浏览器
   }    
   else if(window.ActiveXObject){    
    request=new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器
   }    
   request.onreadystatechange  = function(){  
      if (request.readyState == 4  )  
      {  
        var jsonObj = JSON.parse(request.responseText);//JSON.parse() 返回JSON对象
        document.getElementById("date").innerHTML =  jsonObj.date;  
        document.getElementById("time").innerHTML = jsonObj.time;  
      }  
   }  
   request.open("GET", url, true);  
   request.send();  
}  
</script>  
</head>  
<body>  
  
Date: <span id="date"></span><br/>  
Time: <span id="time"></span><br/>  
  
<button type="button" onclick="load()">Load Information</button>  
</body>  
</html> 

AXIOS

官网

引入AXIOS:

代码语言:javascript复制
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

使用AXIOS发送请求:

Get请求:

代码语言:javascript复制
axios({
    method:"get",
    url:"http://localhost:8080/axios-demo/aJAXDemo?username=ahzoo"
})then(function (resp){
    //回调函数,接收后端返回结果
    alert(resp.data);
})

Post请求:

代码语言:javascript复制
axios({
    method:"post",
    url:"http://localhost:8080/axios-demo/aJAXDemo"
    data:"username=ahzoo"
})then(function (resp){
    //回调函数,接收后端返回结果
    alert(resp.data);
})

后端部分和AJAX一样:

代码语言:javascript复制
public class AjaxServlet extends HttpServlet {
  protected void javaScriptAjax(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    //接受请求参数
    System.out.println("ajax 请求:"   request.getParameter("username"));
    //响应数据
    response.getWrite().write("ouo");
  }
}

请求方式别名

为方便使用,官方为所有支持的请求方法提供了别名,可以直接使用别名来发起请求:

代码语言:javascript复制
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

注意:在使用别名方法时, url、method、data 这些属性都不必在配置中指定。

以Post和Get为例:

代码语言:javascript复制
axios.get("请求地址")
	.then(function (resp){
    alert(resp.data)
})


axios.post("请求地址","参数")
	.then(function (resp){
    alert(resp.data)
})

建议使用原生方式,虽然没有用请求方式别名简洁,但是阅读性较强,一目了然

拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

代码语言:javascript复制
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

如果你想在稍后移除拦截器,可以这样:

代码语言:javascript复制
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

可以为自定义 axios 实例添加拦截器。

代码语言:javascript复制
var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

错误处理:

代码语言:javascript复制
axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。

代码语言:javascript复制
axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // 状态码在大于或等于500时才会 reject
  }
})

业务

浏览器向Http服务器发送请求;

用户向网站发送请求。

比如:

用户A向服务端发送了一个请求,向用户B完成转账业务

0 人点赞