Servlet和Http学习

1. Servlet概述

•Servlet是Server Applet的简称,意思为用Java编写的服务器端的程序,它运行在web服务器中,web服务器负责Servlet和客户的通信以及调用Servlet方法,Servlet和客户通信采用“请求/响应”的模式。

•Servlet的作用:

​ 1.接收用户发送的请求

​ 2.调用其他的java程序来处理请求

​ 3.根据处理结果,服务器将响应返回给客户端
Servlet和Http学习

2. Servlet创建和使用

1.创建一个index.html,制作一个登录表单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
Http协议:超文本传输协议
超链接,提交表单都是属于http请求
一次请求中包含:请求头`请求行`请求体(表单post提交数据)
-->

<form action="login" method="post">
    账号:<input type="text" name="account"><br>

    密码:<input type="password" name="password"><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

2.在WEB_INF中创建lib包,存放jar包,添加jsp-api.jar和servlet-api.jar(地址https://mvnrepository.com)

Servlet和Http学习

3.导入jar包
Servlet和Http学习

Servlet和Http学习
Servlet和Http学习

4.jar包导入以后,选择应用,OK

5.创建.java文件,继承HttpServlet,重写父类方法

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import java.io.IOException;

public class LoginServlet_bank1 extends HttpServlet {
    /*
     * 在客户端第一次访问loginServlet时创建,服务器启动时创建
     * 只被调用一次,只创建一个servlet对象  单实例的
     * 在创建servlet时,应由servlet容器完成,创建实例应在init()之前
     * */
    public LoginServlet_bank1() {
        System.out.println("LoginServlet无参构造方法");
    }

    /*
     * 提供服务器
     * 每次请求都会调用service
     * */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service");
    }

    /*
     * 初始化,在创建对象后,构造方法执行后,调用init方法,完成一些初始化操作
     * 只执行一次
     * 如果没有初始化操作可以不用重写init()方法,服务器会调用init(),调用父类中的方法
     * */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println(config.getInitParameter("count"));
        System.out.println("init");
    }


    /*
    在服务器关闭前,servlet销毁之前调用
    可以在此方法中完成一些最终操作,比如保存日志
    如果没有最终操作,可以不用重写,但会调用父类中的destory方法
     */
    @Override
    public void destroy() {
        System.out.println("destroy");
    }

}

6.在WEB-INF中web.xml进行配置

web.xml:用于存储Web项目配置信息,在服务器启动时,由服务器读取
xml可扩展标展标记语言,主要用于存储数据
 <!-- 配置servlet-->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.ff.firstWeb.serverlet.LoginServlet</servlet-class>
        <!--配置初始化参数-->
        <init-param>
            <param-name>count</param-name>
            <param-value>111111</param-value>
        </init-param>

        <!-- 值<0,第一次访问时创建. 值>=0,在服务器启动时创建       -->
        <load-on-startup>0</load-on-startup>
    </servlet>

	 <!--
    给servlet配置一个访问地址,映射
    反射机制可以根据类的地址动态创建对象
    -->
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

7.启动,即可向服务器发送请求

3.Servlet的生命周期

Servlet和Http学习

4.Http协议

什么是HTTP?

超文本传输协议 (HyperText Transfer Protocol)服务器传输超文本到本地浏览器的传送协议,是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。

HTTP是一个基于TCP/IP通信协议来传递数据.

HTTP是一个属于应用层的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统.

5.Http请求

目前将http请求分为:
1.get:主要从古武器获取数据,也可以向服务器发送数据,数据在地址中传递,会在地址栏中显示    
	超链接   
	在浏览器地址栏中直接输入地址访问    
	js  
		window.open(url)        
		location.assign(url)        
		location.replace(url)    
	表单:method="get"
2.post:向服务器发送数据,提交数据在请求体发送,长度没有限制,数据在请求中相对安全    
	表单:method="post"
	
get和post的区别
get:主要用于从服务器获取数据
	也可以向服务器发送数据,数据在地址中传输,会在地址栏中显示
	长度有限制
	相对不安全
post:主要用于向服务器发送数据
	提交数据在请求体中发送,长度没有限制
	数据在请求体中相对安全

HttpServletRequest是ServletRequest的子接口

HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。

请求和响应是Web交互最基本的模式,在Servlet中,用HttpServletRequest来表示请求。

HttpServletRequest :封装了请求的信息,可以从中获取任何请求信息。

获取客户端/服务器信息

getMethod()//得到客户机请求方式
getScheme()//请求协议
getRemoteAddr()//返回发出请求的客户机的IP地址
getServerName()//服务器名(ip或域名)
getServerPort()//服务器端口
getParameter(name) //--- String 通过name获得值
getParameterValues  //--- String[ ] 通过name获得多值

package com.ff.firstWeb.serverlet;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;

public class LoginServlet_bank2 extends HttpServlet {
    /*
    无参构造方法默认存在
    init()可以不用重写,会调用父类的方法
    servlet可以调用父类的
    get请求--doGet()
    post请求--doPost()
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        String name = req.getParameter("name");
        String age = req.getParameter("age");
        System.out.println(name+"::"+age);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        System.out.println("doPost");
        String acount = req.getParameter("acount");
        String password = req.getParameter("password");
        String sex = req.getParameter("sex");
        String work = req.getParameter("work");
        String[] course = req.getParameterValues("course");
        System.out.println(acount+"::"+password+"::"+sex+"::"+work+"::"+ Arrays.toString(course));

        //请求接收中的数据(请求行,请求头)
        /*System.out.println(req.getMethod());
        System.out.println(req.getRemoteAddr());
        System.out.println(req.getServerName());
        System.out.println(req.getServerPort());
        System.out.println(req.getScheme());
        System.out.println(req.getProtocol());
        System.out.println(req.getContentType());
        System.out.println(req.getContextPath());
        System.out.println(req.getHeader("User-Agent"));
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            System.out.println(name+":"+req.getHeader("name"));
        }*/

        //向客户端做出相应,本质使用IO字符输出流
        PrintWriter out = resp.getWriter();

    }
}

6.Http响应

一个http响应代表服务器向客户端回送的数据,它包括:响应行,响应头,响应体。

响应行里包含了http协议版本,以及用于描述服务器对请求的处理结果。

HTTP/1.1 (协议版本) 200(状态吗) OK(状态码描述)

状态码:服务器和浏览器用于确定状态的固定数字号码

​ 200:请求成功

​ 302:请求重定向

​ 400:语义有误,当前请求无法被服务器理解或请求参数有误

​ 404:请求资源不存在,通常是路径写错了或者服务器资源删除了

​ 500:服务内部错误(代码异常)

响应头用于描述服务器的基本信息,以及数据描述

Server Apache-Coyote/1.1

Content-Type text/html;charset=UTF-8

Content-Length 0

Date Wed, 13 Sep 2017 02:26:07 GMT

响应体代表服务器向客户端浏览器回送的正文

package com.ff.firstWeb.serverlet;

import com.ff.firstWeb.dao.checkDao;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class LoginServlet extends HttpServlet {
    /*
    无参构造方法默认存在
    init()可以不用重写,会调用父类的方法
    servlet可以调用父类
    get请求--doGet()
    post请求--doPost()
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        String account = req.getParameter("account");
        String password = req.getParameter("password");
        //设置响应内容的编码格式
        resp.setHeader("content-type","text/html;charset=utf-8");
        //向客户端做出相应,本质使用IO字符输出流
        PrintWriter out = resp.getWriter();
        Connection connection = null;
        try {
            if (checkDao.link(account, password)) {
                int x = 10/0;
                String ip = req.getRemoteAddr();
                Date date = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String login_time = dateFormat.format(date);
                checkDao.insert(account,ip,login_time);
                out.print("登陆成功");
            } else {
                out.print("密码或账户错误");
            }
        } catch (Exception throwables) {
            throwables.printStackTrace();
            resp.sendRedirect("505.jsp");
        }
    }
}

8.jsp的引入(解决复杂动态页面的响应)

package com.ff.firstWeb.serverlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet_bank3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        System.out.println("doPost");
        String acount = req.getParameter("acount");
        String password = req.getParameter("password");
        System.out.println(acount+"::"+password);

        //设置响应内容的编码格式
        resp.setHeader("content-type","text/html;charset=utf-8");
        //向客户端做出相应,本质使用IO字符输出流
        PrintWriter out = resp.getWriter();
        if (acount.equals("admin") && password.equals("111")){
            //早期的动态页面就是从servlet中输出的
            out.print("登陆成功");
            out.print("<Html>");
            out.print("<head>");
            out.print("</head>");
            out.print("<body>");
            for (int i = 0; i < 10; i++) {
                out.print("<h1>"+i+"</h1>");
            }
            out.print("</body>");
            out.print("</Html>");

            //问题:响应的页面十分复杂
            //解决方法:使用jsp的动态页面,本质也是servlet,作用是向客户端响应内容
        }else{
            out.print("账号或密码失败");
        }
    }
}

在jsp中书写java代码需要<%%>包含起来

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<% for (int i = 0; i < 10; i++) {%>
<h1>动态信息<%System.out.println(i)%></h1>
<%
    }
%>
</body>
</html>
上一篇:解决:NACOS 异常com.alibaba.nacos.api.exception.NacosException: failed to req API:/api//nacos/v1/ns/insta


下一篇:(17)UVM sequencer和driver