01Javaee第一章Servlet

本文介绍了Web开发的基本概念,如Web服务器、Tomcat和Apache的区别。详细阐述了如何搭建Java EE的开发环境,特别是Tomcat的安装与配置。接着讲解了Servlet的概述、创建和使用,包括Servlet的配置、HTTP协议的理解以及如何处理HTTP请求和响应。最后,文章还提到了Ajax的基础知识和跨域问题的重要性。

web开发概述

Web服务器是指驻留于因特网上某种类型计算机的程序。

可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界浏览;它是一个容器,是一个连接用户与程序之间的中间件。

WEB服务器有很多,流行的WEB服务器有Tomcat 、 WebSphere 、WebLogic、Jboss等。

在小型的应用系统或者有特殊需要的系统中,可以使用一个免费的Web服务器:Apache 的Tomcat,该服务器支持全部JSP以及Servlet规范。

Apache软件基金会(也就是Apache Software Foundation,),是专门为运作一个开源软件项目的 Apache 的团体提供支持的非盈利性组织。

服务器:

  • 狭义 服务器指的是一款软件,放文件,可以远程请求访问,服务器就会做出响应。
  • 广义 电脑+软件

服务器是一个容器(部署项目)是一个连接客户端与服务端的中间件。

web开发环境搭建

Tomcat官方站点:http://tomcat.apache.org

获取Tomcat安装程序包

  • tar.gz文件是Linux操作系统下的安装版本

  • zip文件是Windows系统下的压缩版本

安装JDK

  • 设置JAVA_HOME环境变量 jdk根目录

  • 设置PATH环境变量

安装Tomcat

  • 解压tomcat压缩文件

启动

  • 双击 bin 目录下的 startup.bat 文件

访问:IP+端口

  • 输入 http://localhost:端口号 或http:127.0.0.1:端口号 或局域网ip:端口号

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lN45awSQ-1646053678783)(E:\学习笔记\JavaEE\图\Tomcat 的目录层次结构.png)]

bin/startup.bat 运行servlet bin/shutdown.bat 关闭servlet

conf配置文件

conf/server.xml 中可改变端口号。

webapps 部署web项目

web开发环境搭建

创建并发web项目

1.在开发工具中创建一个web project

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKm1x0g1-1646053678786)(E:\学习笔记\JavaEE\图\web开发环境搭建.jpg)]

2.在webContent中创建index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
      javaee
</body>
</html>

3.发布web应用到服务器,发布应用有两种方式:

  • 方式1:手动发布

    将项目下web目录中的文件复制到服务器webapps目录下,并在此目录中创建新的helloword根目录。

  • 方式2:自动发布

    自动将web应用发布到web服务器下,需要在开发工具中集成tomcat进来

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4XJsmRq-1646053678788)(E:\学习笔记\JavaEE\图\自动发布1.jpg)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2bKycI0B-1646053678789)(E:\学习笔记\JavaEE\图\自动发布2.jpg)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fCdzoVVD-1646053678790)(E:\学习笔记\JavaEE\图\自动发布3.jpg)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teb7WQpC-1646053678791)(E:\学习笔记\JavaEE\图\自动发布4.jpg)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hp2q3ZRz-1646053678793)(E:\学习笔记\JavaEE\图\自动发布5.png)]

4.访问:打开浏览器访问http:localhost:8080/项目名/index.html

Servlet概述

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

Servlet的作用:

  • 接收用户发送的请求
  • 调用其他的java程序来处理请求
  • 根据处理结果,服务器将响应返回给客户端

Servlet创建和使用

1.创建一个类继承javax.servlet.http包下的HttpServlet

2.在web.xml文件中配置Servlet

3.运行Servlet程序:通过浏览器访问http:localhost:8080/ helloword/配置的url-pattern

由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被 外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用元素和元素完成。

Servlet配置

元素用于注册Servlet,它包含有两个主要的子元素:和,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:和,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

url-pattern配置模式:”/”代表当前web应用的根目录精确匹配

例如/test 访问http://127.0.0.1/myapp/test

myServlet

/test

package com.ffyc.webback.servlet;

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

/*
  创建一个类,继承HttpServlet
  重写方法
  配置servlet
  
    Servlet
       接收客户端请求
       调用其他的java程序处理请求
       响应

   Servlet对象生命周期
     servlet对象创建:
          默认 在第一次访问Servlet时,由服务器创建对象,只创建了一次.
          <load-on-startup>0</load-on-startup> 在服务器启动时........
          调用构造方法,只调用一次
     Servlet对象初始化:  init 在servlet对象创建成功后,紧接着会初始化Servlet
      服务阶段 : service  每次请求都会到达service
                 接收
                 处理
                 响应
      销毁阶段: 当servlet对象销毁时(正常关闭服务器,卸载servlet对象), 执行destroy()  只执行一次
 */
public class DemoServlet extends HttpServlet {
    /*
      构造方法
    */
    public DemoServlet() {
        System.out.println("无参构造方法");
    }

    /*
      初始化,例如获取配置文件中的参数信息
      只执行一次,在构造方法执行完成后执行
    */
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
    }

    /*
      提供服务,多次执行
      服务器将请求中的数据封装到HttpServletRequest对象中
       jdbc java只提供了标准接口  具体的实现由不同的数据库开发商实现

       servlet 定义了两个接口HttpServletRequest请求,HttpServletResponse响应
                由tomcat中的类具体实现 org.apache.catalina.connector.RequestFacade
    */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("service");
    }

    /*
       销毁: 在servlet对象销毁前,执行一些操作
       例如保存日志
    */
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <!--
       xml 可扩展标记语言 必须有一个根标签
       web.xml  是web项目的配置文件(servlet 过滤器……),服务器启动时,由服务器读取
    -->
    <!--配置注册servlet-->
    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.ffyc.webback.servlet.DemoServlet</servlet-class>
    </servlet>
    <!--为servlet配置访问地址-->
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demo</url-pattern>  <!--供外界访问的地址   /表示到项目名   ip+端口/webback/demo 进行访问-->
    </servlet-mapping>
</web-app>

创建发布web项目- web.xml文件

Web.xml文件为web应用的配置文件,它必须放在web应用目录WEB-INF目录下。

Web.xml文件用于对web应用下的web资源进行配置,服务器在启动时会读取web.xml文件中的内容。

Http协议

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

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

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

http请求

客户端连上服务器后,向服务器请求某个web资源,称之为客户端向服务器发送了一个http请求。

请求包括: 请求行,请求头,请求体 。

请求行包含http请求方式,请求资源名称,http版本 。

请求头包含主机地址,以及客户端的一些环境信息,以键值对的形式传递.

Host: 127.0.0.1:8088 请求的主机地址

Accept:

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8浏览器能够处理的内容类型

Accept-Encoding: gzip, deflate, br 浏览器能够处理的压缩编码

Accept-Language: zh-CN,zh;q=0.9 浏览器当前设置的语言

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36 使用的浏览器和操作平台信息

Connection: keep-alive 浏览器与服务器之间连接的类型

请求体代表着浏览器在post请求方式中传递给服务器的参数,请求体中参数以键值形式传递,

多个用&链接,服务器接收到后再解析。

username=admin&userpwd=123

GET方式:

  • 超链接访问,默认是GET方式

  • form提交,不指定method,默认为GET方式

POST方式:

  • form提交,指定method=“POST”

Get方式与post方式的区别 :

  • Get方式主要是从服务器获取信息;post主要是想服务器提交信息

  • Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在请求体中提交。

  • GET方式提交的数据大小受限制一般1kb(不同浏览器也会有不同);而POST则没有此限制。

public class LoginServlet extends HttpServlet {

    //无参构造   默认存在
    //init      如果我们没有什么可以初始化的内容,可以不重写init, 会调用父类中的init
    //service   请求过来后,会先调用父类中的service,service中根据不同的请求方式,判断调用哪个方法处理
    //destroy   如果销毁前没有什么可以执行的操作,destroy()可以不重写,会调用父类中的destroy.


    /*
       dopost() 处理post方式的http请求
       请求中的数据到达服务器之后,会将数据封装到HttpServletRequest中(实际是一个子类对象)
       通过此对象接收请求中的数据

       响应对象HttpServletResponse
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("dopost");
    }

    /*
      doget()处理get方式的http请求
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--
  xml   可扩展标记语言   标记语言必须有一个根标签
  web.xml  是wenb项目的配置文件(servlet 过滤器...),在服务器启动时,由服务器读取
-->
  <!--配置注册servlet-->
    <servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>com.ffyc.webback.servlet.DemoServlet</servlet-class><!--由服务器通过反射机制创建对象-->
            <!--为Servlet配置参数-->
            <init-param>
                <param-name>name</param-name>
                <param-value>张三</param-value>
            </init-param>
        <load-on-startup>0</load-on-startup><!--何时创建Servlet对象-->
    </servlet>
    <!--为servlet配置访问地址-->
    <servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/demo</url-pattern> <!-- /表示到项目名   ip+端口/webback/demo-->
    </servlet-mapping>

    <!-- 配置登录servlet  -->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.ffyc.webback.servlet.LoginServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
		<!-- 
		    http请求
			   包含请求行,请求头  由浏览器提交
			       请求体: post方式向服务器发送的数据
				   
				http的常用两种请求方式
				   get :  超链接, form method="get"
				   post: form method="post"
				   
				   区别:
				     get
					    主要用于从服务器获取数据, 传少量的信息,有限制
					    
					 post
					     主要用于向服务器发送数据,大量发送,没有限制
		 -->
		<form action="http://127.0.0.1:8888/webback/login" method="post">
			账号:<input type="text" name="account" value=""/> <br/>
			密码:<input type="password" name="password" /><br/>
			    <input type="submit" value="登录" />
		</form>
	</body>
</html> 
登录案例
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		
	</head>
	<body>
		<form action="http://127.0.0.1:8080/webback/login" method="post">
			账号<input type="text" name="account"/><br>
			密码<input type="password" name="password" /><br>
			<input type="submit" value="登录" />
		</form>
	</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--login-->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.ffyc.webback.servlet.LoginServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>
package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;

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.sql.SQLException;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {

    //无参构造   默认存在
    //init      如果我们没有什么可以初始化的内容,可以不重写init, 会调用父类中的init
    //service   请求过来后,会先调用父类中的service,service中根据不同的请求方式,判断调用哪个方法处理
    //destroy   如果销毁前没有什么可以执行的操作,destroy()可以不重写,会调用父类中的destroy.


    /*
       dopost() 处理post方式的http请求
       请求中的数据到达服务器之后,会将数据封装到HttpServletRequest中(实际是一个子类对象)
       通过此对象接收请求中的数据

       响应对象HttpServletResponse
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("dopost");
        //接收
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println(account+":"+password);

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();
        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password); //把从客户端得到的数据传给login()调用数据库查看数据是否匹配
            if(user==null){
                resp.getWriter().println("账号或密码错误");
            }else {
                resp.getWriter().println("登录成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试");
        }
        //响应
        /*resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("账号或密码错误");*/
    }
}
package com.ffyc.webback.dao;

import com.ffyc.webback.model.User;

import java.sql.*;

public class LoginDao {
    public User login(String account, String password) throws ClassNotFoundException, SQLException {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        User user = null;
        try{
            //连接数据库
            Class.forName("com.mysql.cj.jdbc.Driver"); //加载驱动,用到反射机制
            String url = "jdbc:mysql://127.0.0.1:3306/web_db?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
            //ConnectionImpl是Connection接口的实现类
            connection = DriverManager.getConnection(url,"root","shijie");
            //预编译
            ps = connection.prepareStatement("SELECT id,account FROM USER WHERE account = ? AND PASSWORD = ?");
            //执行
            ps.setObject(1,account);
            ps.setObject(2,password);
            //返回ResultSet executeQuery()下达数据库select指令查询数据库,存放在ResultSet类中供我们使用
            rs = ps.executeQuery();
            while (rs.next()){
                user = new User();
                user.setId(rs.getInt("id"));
                user.setAccount(rs.getString("account"));
                return user;
            }
            return user; //user为null
        }finally {
            if(rs!=null){
                rs.close();
            }
            if(ps!=null){
                ps.close();
            }
            if(connection!=null){
                connection.close();
            }
        }
    }
}
package com.ffyc.webback.model;

public class User {
    private int id;
    private String account;
    private String password;
    private String gender;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}
补充

post方式的请求,中文会乱码,需要指定解码格式。

单选,下拉框 只会提交选中的选项

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		
	</head>
	<body>
		<form action="http://127.0.0.1:8080/webback/login" method="post">
			账号<input type="text" name="account"/><br>
			密码<input type="password" name="password" /><br>
			<!-- 单选,下拉框 只会提交选中的选项 -->
			性别<input type="radio" name="gender" value="" /><input type="radio" name="gender" value="" /><br>
			爱好<input type="checkbox" name="hobby" value="打游戏" />打游戏
				<input type="checkbox" name="hobby" value="写代码"/>写代码
				<input type="checkbox" name="hobby" value="看书" />看书
			<input type="submit" value="登录" />
		</form>
	</body>
</html>
package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;

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.sql.SQLException;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {

    //无参构造   默认存在
    //init      如果我们没有什么可以初始化的内容,可以不重写init, 会调用父类中的init
    //service   请求过来后,会先调用父类中的service,service中根据不同的请求方式,判断调用哪个方法处理
    //destroy   如果销毁前没有什么可以执行的操作,destroy()可以不重写,会调用父类中的destroy.


    /*
       dopost() 处理post方式的http请求
       请求中的数据到达服务器之后,会将数据封装到HttpServletRequest中(实际是一个子类对象)
       通过此对象接收请求中的数据

       响应对象HttpServletResponse
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("dopost");
        //接收请求
        //
        req.setCharacterEncoding("utf-8");
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        String gender = req.getParameter("gender");
        String[] hobby = req.getParameterValues("hobby"); //接受多个name相同的数据
        System.out.println(account+":"+password+":"+gender+":"+Arrays.toString(hobby));

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();
        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password); //把从客户端得到的数据传给login()调用数据库查看数据是否匹配
            if(user==null){
                resp.getWriter().println("账号或密码错误");
            }else {
                resp.getWriter().println("登录成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试");
        }
        //响应
        /*resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("账号或密码错误");*/
    }
}
HttpServletRequest

HttpServletRequest是ServletRequest的子接口,HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。

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

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

● getMethod()得到客户机请求方式

● getScheme()请求协议

● getRemoteAddr()返回发出请求的客户机的IP地址

● getServerName()服务器名(ip或域名)

● getServerPort()服务器端口

● getParameter(name) — String 通过name获得值

● getParameterValues — String[ ] 通过name获得多值

● 理中文乱码

post

​ setCharacterEncoding(编码格式)

package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;

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.sql.SQLException;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {

    //无参构造   默认存在
    //init      如果我们没有什么可以初始化的内容,可以不重写init, 会调用父类中的init
    //service   请求过来后,会先调用父类中的service,service中根据不同的请求方式,判断调用哪个方法处理
    //destroy   如果销毁前没有什么可以执行的操作,destroy()可以不重写,会调用父类中的destroy.


    /*
       dopost() 处理post方式的http请求
       请求中的数据到达服务器之后,会将数据封装到HttpServletRequest中(实际是一个子类对象)
       通过此对象接收请求中的数据

       响应对象HttpServletResponse
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("dopost");
        //接收表单请求数据
        //post方式的请求,中文会乱码,需要指定解码格式
        req.setCharacterEncoding("utf-8");
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        String gender = req.getParameter("gender");
        String[] hobby = req.getParameterValues("hobby"); //接受多个name相同的数据
        //接受请求头,请求行中的数据
        System.out.println(req.getMethod()); //获得请求方式
        System.out.println(req.getHeader("Accept-Language")); //获得请求方式
        System.out.println(req.getRemotePort()); //请求远端端口
        System.out.println(req.getRemoteAddr()); //获得远端IP
        System.out.println(req.getServerName()); //获得服务器主机名
        System.out.println(req.getServerPort()); //获得服务器端口号
        System.out.println(req.getProtocol()); //获得协议
        System.out.println(req.getScheme()); //获得http
        System.out.println(req.getServletContext()); //获得上下文

        System.out.println(account+":"+password+":"+gender+":"+Arrays.toString(hobby));

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();
        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password); //把从客户端得到的数据传给login()调用数据库查看数据是否匹配
            if(user==null){
                resp.getWriter().println("账号或密码错误");
            }else {
                resp.getWriter().println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试");
        }
        //响应
        /*resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("账号或密码错误");*/
    }
}

http响应

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

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

HttpServletResponse

HttpServletResponse是ServletResponse的子接口 。

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个代表响应的HttpServletResponse对象。

HttpServletResponse对象代表响应。

用getWriter()获得一个PrintWriter字符输出流输出数据response会默认以ISO8859-1将需要输出到浏览器的字符进行解码,如果输出的字符在ISO8859-1中不存在,就会导致乱码问题。

response.setContetnType(“text/html;charset=utf-8”);方法可以同时设定response所使用的字符集编码和浏览器打开所用的字符集编码。

public class LoginServlet extends HttpServlet {
    @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");
        String gender = req.getParameter("gender");
        String[] hobby = req.getParameterValues("hobby"); //接受多个name相同的数据
        //接受请求头,请求行中的数据
        System.out.println(req.getMethod()); //获得请求方式
        System.out.println(req.getHeader("Accept-Language")); //获得请求方式
        System.out.println(req.getRemotePort()); //请求远端端口
        System.out.println(req.getRemoteAddr()); //获得远端IP
        System.out.println(req.getServerName()); //获得服务器主机名
        System.out.println(req.getServerPort()); //获得服务器端口号
        System.out.println(req.getProtocol()); //获得协议
        System.out.println(req.getScheme()); //获得http
        System.out.println(req.getServletContext()); //获得上下文
        System.out.println(account+":"+password+":"+gender+":"+Arrays.toString(hobby));
        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();
        /*
          http响应
            包含响应头
               响应行(http响应状态码 200:请求响应成功 404:资源不存在,路径错误 500:服务器内部代码报错)
               响应体
        */
//        resp.setHeader("Content-Type","text/html;charset=utf-8"); 设置响应编码
        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password); //把从客户端得到的数据传给login()调用数据库查看数据是否匹配
            if(user==null){
                resp.getWriter().println("账号或密码错误"); //响应体(数据)
            }else {
                resp.getWriter().println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试"); 
        }
        //响应
        /*resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("账号或密码错误");*/
    }
}

Ajax

● Ajax 全称为:“Asynchronous JavaScript and XML”(异步JavaScript 和 XML), 使用 Ajax,我们可以无刷新状态更新页面,并且实现异步提交,提升了用户体验。

● Ajax其实质是利用浏览器提供的一个特殊的对象(XMLHttpRequest) 异步地向服务器发送请求,

● 服务器返回部分数据,浏览器让你去利用这些数据对页面做部分的更新,整个过程,页面无刷新,不打断用户的操作。

创建 XMLHttpRequest 对象

● XMLHttpRequest对象:发送请求到服务器并获得返回结果

● 所有现代浏览器 都内建了 XMLHttpRequest 对象,通过一行简单的

JavaScript 代码,我们就可以创建 XMLHttpRequest 对象。

● new XMLHttpRequest();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GPBjaI8-1646053678795)(E:\学习笔记\JavaEE\图\就绪状态码.png)]

不覆盖内容

加入过滤器

package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收表单请求数据
        req.setCharacterEncoding("utf-8");
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println(account+":"+password);

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();

        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password);
            if(user==null){
                resp.getWriter().println("账号或密码错误");
            }else {
                resp.getWriter().println(user);//响应的数据格式还要发生变化
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试");
        }
    }
}
package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收表单请求数据
        req.setCharacterEncoding("utf-8");
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println(account+":"+password);

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();

        resp.setContentType("text/html;charset=utf-8"); //设置响应编码 json
        try {
            User user = loginDao.login(account, password);
            if(user==null){
                resp.getWriter().println("账号或密码错误");
            }else {
                resp.getWriter().println(user);//响应的数据格式还要发生变化
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println("系统忙,请稍后再试");
        }
    }
}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript">
			function login(){
				var account = document.getElementById("accountid").value;
				var password = document.getElementById("passwordid").value;
				//表单验证
				 //return;
				//发起ajax请求
				//创建XMLHttpRequest对象
				var  httpobj = new XMLHttpRequest();
				    // 地址?之后就是传输的数据
				     httpobj.open("GET","http://127.0.0.1:8080/webback/login?account="+account+"&password="+password,true);//封装请求数据
					 httpobj.send();//发送请求
					//接收后端响应的内容  onreadystatechange是一个事件,此事件在请求发送完成后执行,值是一个匿名函数
					httpobj.onreadystatechange = function(resp){
						// alert(httpobj.readyState);
						if(httpobj.readyState==4){ //当读取响应内容结束后获取响应内容,输出到页面
							// alert(httpobj.responseText);
							document.getElementById("accountMsgId").innerHTML = httpobj.responseText;
						}
					}
					
					
					
			}		
		</script>
	</head>
	<body>
		<!-- 
		   发起请求方式要发生改变
		   昨天直接提交表单到后端服务器,后端服务器直接进行响应,响应内容将浏览器页面覆盖掉,这种方式是同步请求方式.
		   
		   前后端分离的情况下,都使用异步方式请求:
		    异步就是不同步: 发送请求和页面操作不冲突.
			   发送异步请求,需要用到浏览器中提供的一个对象 XMLHttpRequest对象,使用此对象向服务器发送请求,
			   服务器端响应回来的内容,也是被此对象接收的.
		   
		       使用ajax请求,向另一个后端服务发送请求时,浏览器为了安全考虑,默认不允许接收另一个服务响应的内容
			   称为跨域问题( 如果请求协议,域名,端口)有一个不同,就是跨域访问.
			   解决: 前端解决    后端解决(向前端响应一个标识,表示是安全的,浏览器就可以接收了)
		 -->
		<form>
			账号:<input type="text" name="account" value="" id="accountid"/> <br/>
			<span id="accountMsgId"></span><br>
			密码:<input type="password" name="password" id="passwordid"/><br/>
			    <input type="button" value="登录"  onclick="login()"/>
		</form>
	</body>
</html>

跨域问题

什么是跨域?

跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com 页面去请求 www.google.com 的资源。但是一般情况下不能这么做,它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域.

所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域。

默认端口是80端口

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交 换格式

● 数据在键值对中

● 数据由逗号分隔

● 大括号保存对象

● 方括号保存数组

语法:

JSON 键值对是用来保存 JS 对象的一种方式,和 JS 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:

{“firstName”: “John”} {“name”:”value”,”sex”:”男”}

package com.ffyc.webback.model;

public class User {
    private int id;
    private String account;
    private String password;
    private String gender;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", account='" + account + '\'' +
                ", password='" + password + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;
import com.google.gson.Gson;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收表单请求数据
        req.setCharacterEncoding("utf-8");
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println(account+":"+password);

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();

        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password);
            if(user==null){
                resp.getWriter().println(0);
            }else {
                //响应的数据格式要发生变化 json
                /*
                  后端向前端响应数据时,大家都遵循一个规范,统一的格式(json)
                  两种语言对象结构不同的,重点是数据的传输
                  java对象-->json格式的字符串-->前端-->js转为js对象
                  "{id:1,account:'admin',password:'qqqq'}" --> 表示一个java对象
                  [{id:1,account:'admin',password:'qqqq'},{id:1,account:'admin',password:'qqqq'}] -->表示一个集合
                */
                Gson gson = new Gson();
                String json = gson.toJson(user);
                System.out.println(json);
                resp.getWriter().println(json);//直接打印对象,默认调用对象toString()
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println(1);
        }
    }
}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript">
			function login(){
				var account = document.getElementById("accountid").value;
				var password = document.getElementById("passwordid").value;
				//表单验证
				 //return;
				//发起ajax请求
				//创建XMLHttpRequest对象
				var  httpobj = new XMLHttpRequest();
				    // 地址?之后就是传输的数据
				     httpobj.open("GET","http://127.0.0.1:8080/webback/login?account="+account+"&password="+password,true);//封装请求数据
					 httpobj.send();//发送请求
					//接收后端响应的内容  onreadystatechange是一个事件,此事件在请求发送完成后执行,值是一个匿名函数
					httpobj.onreadystatechange = function(resp){
						// alert(httpobj.readyState);
						if(httpobj.readyState==4){ //当读取响应内容结束后获取响应内容,输出到页面
							// alert(httpobj.responseText);
							//document.getElementById("accountMsgId").innerHTML = httpobj.responseText;
							if(httpobj.responseText==0){
								document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
							}else if(httpobj.responseText==1){
								document.getElementById("accountMsgId").innerHTML = "系统忙";
							}else{
								//登录成功后,跳转成功页面
								httpobj.responseText;
								location.assign("main.html");
							}
						}
					}
					
					
					
			}		
		</script>
	</head>
	<body>
		<!-- 
		   发起请求方式要发生改变
		   昨天直接提交表单到后端服务器,后端服务器直接进行响应,响应内容将浏览器页面覆盖掉,这种方式是同步请求方式.
		   
		   前后端分离的情况下,都使用异步方式请求:
		    异步就是不同步: 发送请求和页面操作不冲突.
			   发送异步请求,需要用到浏览器中提供的一个对象 XMLHttpRequest对象,使用此对象向服务器发送请求,
			   服务器端响应回来的内容,也是被此对象接收的.
		   
		       使用ajax请求,向另一个后端服务发送请求时,浏览器为了安全考虑,默认不允许接收另一个服务响应的内容
			   称为跨域问题( 如果请求协议,域名,端口)有一个不同,就是跨域访问.
			   解决: 前端解决    后端解决(向前端响应一个标识,表示是安全的,浏览器就可以接收了)
		 -->
		<form>
			账号:<input type="text" name="account" value="" id="accountid"/> <br/>
			<span id="accountMsgId"></span><br>
			密码:<input type="password" name="password" id="passwordid"/><br/>
			    <input type="button" value="登录"  onclick="login()"/>
		</form>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		
	</head>
	<body onload="showUserInfo()">
		<!-- 登录成功后,需要在此页面显示用户信息 -->
		登录成功
	</body>
</html>

Java对象转JSON

● 在异步交换数据时,java对象不能直接被传递给js,所以需要先把java对 象转换为JSON格式字符串,把字符串响应给客户端,再由客户端将JSON字符串转换为js对象即可。eval("("+jsonStr+")")

借助浏览器存储信息:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script type="text/javascript">
			function login(){
				var account = document.getElementById("accountid").value;
				var password = document.getElementById("passwordid").value;
				//表单验证
				 //return;
				//发起ajax请求
				//创建XMLHttpRequest对象
				var  httpobj = new XMLHttpRequest();
				    // 地址?之后就是传输的数据
				     httpobj.open("GET","http://127.0.0.1:8080/webback/login?account="+account+"&password="+password,true);//封装请求数据
					 httpobj.send();//发送请求
					//接收后端响应的内容  onreadystatechange是一个事件,此事件在请求发送完成后执行,值是一个匿名函数
					httpobj.onreadystatechange = function(resp){
						// alert(httpobj.readyState);
						if(httpobj.readyState==4){ //当读取响应内容结束后获取响应内容,输出到页面
							// alert(httpobj.responseText);
							//document.getElementById("accountMsgId").innerHTML = httpobj.responseText;
							if(httpobj.responseText==0){
								document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
							}else if(httpobj.responseText==1){
								document.getElementById("accountMsgId").innerHTML = "系统忙";
							}else{
								//登录成功后,跳转成功页面
								/* httpobj.responseText;
								location.assign("main.html"); */
								/*
								localStorage   浏览器本地数据存储   可以长久保存,只要不删除,一直存在
								sessionStorage 浏览器本地数据存储   如果浏览器关闭了信息就会失效
								localStorage.setItem("name","jim");
								*/
							    sessionStorage.setItem("userInfo",httpobj.responseText);
							    location.assign("main.html");
							}
						}
					}
					
					
					
			}		
		</script>
	</head>
	<body>
		<!-- 
		   发起请求方式要发生改变
		   昨天直接提交表单到后端服务器,后端服务器直接进行响应,响应内容将浏览器页面覆盖掉,这种方式是同步请求方式.
		   
		   前后端分离的情况下,都使用异步方式请求:
		    异步就是不同步: 发送请求和页面操作不冲突.
			   发送异步请求,需要用到浏览器中提供的一个对象 XMLHttpRequest对象,使用此对象向服务器发送请求,
			   服务器端响应回来的内容,也是被此对象接收的.
		   
		       使用ajax请求,向另一个后端服务发送请求时,浏览器为了安全考虑,默认不允许接收另一个服务响应的内容
			   称为跨域问题( 如果请求协议,域名,端口)有一个不同,就是跨域访问.
			   解决: 前端解决    后端解决(向前端响应一个标识,表示是安全的,浏览器就可以接收了)
		 -->
		<form>
			账号:<input type="text" name="account" value="" id="accountid"/> <br/>
			<span id="accountMsgId"></span><br>
			密码:<input type="password" name="password" id="passwordid"/><br/>
			    <input type="button" value="登录"  onclick="login()"/>
		</form>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript">
			function showUserInfo(){
				var s = sessionStorage.getItem("userInfo");
				if(s==null){
					location.replace("login.html");
					return;
				}
				//前端把JSON字符串转为js对象{"id":1,"account":"admin"} 早期用的是xml
				var userobj = eval("("+s+")")
				document.getElementById("id").innerHTML = userobj.id;
				document.getElementById("accountid").innerHTML = userobj.account;
			}
		</script>
	</head>
	<body onload="showUserInfo()">
		<!-- 登录成功后,需要在此页面显示用户信息 -->
		<div>
			<span id="id"></span>
			<span id="accountid"></span>
		</div>
	</body>
</html>

axios框架

● 下载axios文件https://unpkg.com/axios/dist/axios.min.js

● 导入项目

● get请求

​ axios.get(’/user?ID=12345’).then(function (response) {

​ console.log(response);

​ })

post请求

axios.post(’/user’, {firstName: ‘Fred’,lastName: ‘Flintstone’ })

.then(function (response) {

​ console.log(response);

​ })

● 响应结果格式

axios.get(’/user/12345’)

.then(function(response) {

console.log(response.data);//后端返回数据,默认为json格式

console.log(response.status);

console.log(response.statusText);

console.log(response.headers);

console.log(response.config);

});

● 向服务器发送cookie数据设置

axios.defaults.withCredentials=true;

过滤器

Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Servlet, 从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

作用:对服务器web资源进行拦截(权限控制,通过拦截资源进行权限控制,是否可以访问)

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。

Servlet API 中,与过滤器有关的API共有三个接口,分别是

  • Filter
  • FilterChain
  • FilterConfig

Filter接口是过滤器类必须实现的接口,该接口中有三个方法。

  • init(FilterConfig filterConfig):该方法是对filter对象进行初始化的方法,仅在容器初始化filter对象结束后被调用一次。参数FilterConfig可以获得filter的初始化参数。

  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain):该方法是filter进行过滤操作的方法,是最重要的方法。过滤器实现类必须实现该方法。方法体中可以对request和response进行预处理。其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资源。

  • destroy():该方法在容器销毁过滤器对象前被调用。

该接口类型作为Filter接口中doFilter方法的参数使用。FilterChain接口中有一个方法

  • doFilter(ServletRequest request,ServletResponse response),该方法可以将当前的请求和响应传递到过滤链上的下一个资源,可能是下一个过滤器,也可能是目标资源。

该接口类型作为Filter接口中的init方法的参数使用,FilterConfig接口中有一个常用方法

  • getInitParameter(String name),该方法用来获得过滤器的初始化参数值。在web.xml中,可以为每一个filter配置需要的初始化参数,与Servlet的类似。过滤器的初始化参数即可通过FilterConfig中的getInitParameter方法获取。

过滤器功能

过滤器用来实现通用的功能,减少代码冗余,提高可维护性

一个过滤器可以配置给多个资源使用

一个资源也可以配置多个过滤器,按照配置顺序调用


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- 导入axios js包 -->
		<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function login(){
				var account = document.getElementById("accountid").value;
				var password = document.getElementById("passwordid").value;
				//表单验证
				 //return;
				//发起ajax请求 发起get(地址).then() 回调函数
				/* axios.get("http://127.0.0.1:8080/webback/login?account="+account+"&password="+password");
					.then(function(resp){
						// console.log(resp); //resp
					   if(resp.data==0){
						   document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
					   }else if(resp.data==1){
						   document.getElementById("accountMsgId").innerHTML = "系统忙";
					   }else{
						   
						    // 响应中关注数据
						   // resp.data 响应回来的数据,默认情况下,已经转为js对象
						   
						   sessionStorage.setItem("id",resp.data.id);
						   sessionStorage.setItem("account",resp.data.account);
						   location.replace("main.html");
					   } 
					}) */
					
					axios.post("http://127.0.0.1:8080/webback/login",
					          "account="+account+"&password="+password)
						.then(function(resp){
							// console.log(resp); //resp
						   if(resp.data==0){
							   document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
						   }else if(resp.data==1){
							   document.getElementById("accountMsgId").innerHTML = "系统忙";
						   }else{
							   /*
							     响应中关注数据
							     resp.data 响应回来的数据,默认情况下,已经转为js对象
							   */
							   sessionStorage.setItem("id",resp.data.id);
							   sessionStorage.setItem("account",resp.data.account);
							   location.replace("main.html");
						   } 
					})
			}		
		</script>
	</head>
	<body>
		<form>
			账号:<input type="text" name="account" value="" id="accountid"/> <br/>
			<span id="accountMsgId"></span><br>
			密码:<input type="password" name="password" id="passwordid"/><br/>
			    <input type="button" value="登录"  onclick="login()"/>
		</form>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function showUserInfo(){
				var id = sessionStorage.getItem("id"); 
				var account = sessionStorage.getItem("account");
				if(account==null){
					location.replace("login.html");
					return;
				}
				document.getElementById("id").innerHTML=id;
				document.getElementById("accountid").innerHTML=account;
			}

		</script>
	</head>
	<body onload="showUserInfo()">
		<!-- 登录成功之后,需要在此页面显示用户信息 -->
		<div>
			<span id="id"></span>
			<span id="accountid"></span>
		</div>
	</body>
</html>
package com.ffyc.webback.servlet;

import com.ffyc.webback.dao.LoginDao;
import com.ffyc.webback.model.User;
import com.google.gson.Gson;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收表单请求数据
//        req.setCharacterEncoding("utf-8"); 重写于过滤器中
        //HttpServletRequest表示客户端的请求 getParameter() String通过name获得值
        String account  = req.getParameter("account");
        String password = req.getParameter("password");
        System.out.println(account+":"+password);

        //处理 把账号,密码传递到 Dao层   与数据库进行交互查询,返回一个结果
        LoginDao loginDao = new LoginDao();

        resp.setContentType("text/html;charset=utf-8"); //设置响应编码
        try {
            User user = loginDao.login(account, password);
            if(user==null){
                resp.getWriter().println(0);
            }else {
                //响应的数据格式要发生变化 json
                /*
                  后端向前端响应数据时,大家都遵循一个规范,统一的格式(json)
                  两种语言对象结构不同的,重点是数据的传输
                  java对象-->json格式的字符串-->前端-->js转为js对象
                  "{id:1,account:'admin',password:'qqqq'}" --> 表示一个java对象
                  [{id:1,account:'admin',password:'qqqq'},{id:1,account:'admin',password:'qqqq'}] -->表示一个集合
                */
                Gson gson = new Gson();
                String json = gson.toJson(user);
                System.out.println(json);
                resp.getWriter().println(json);//直接打印对象,默认调用对象toString()
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.getWriter().println(1);
        }
    }
}
package com.ffyc.webback.filter;

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

/*编码过滤器*/
public class EncodingFilter implements Filter { //Filter 用servlet接口
    //过滤器生命周期开始于服务器的启动
    String charset;

    //init()
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("编码过滤器初始化");
        charset = filterConfig.getInitParameter("charset");
    }

    /*
          过滤器需要执行的功能
    */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("编码过滤器");
        servletRequest.setCharacterEncoding(charset);
        //filterChain(过滤链) 让请求离开过滤器,继续向下执行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    //destroy()
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--
       xml 可扩展标记语言 必须有一个根标签
       web.xml  是web项目的配置文件(servlet 过滤器……),服务器启动时,由服务器读取
    -->
    <!--配置注册servlet-->
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.ffyc.webback.servlet.LoginServlet</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern> <!--定义url-->
    </servlet-mapping>

    <!--配置过滤器-->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.ffyc.webback.filter.EncodingFilter</filter-class>
        <!--为过滤器配置参数-->
        <init-param>
            <param-name>charset</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <!--配置那些请求可以进入到此过滤器中-->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>  <!--配置已有地址 表示所有的请求都可以进入到过滤器中-->
    </filter-mapping>
</web-app>

web回话跟踪机制

● 从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话。

● 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

● 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。

● Session是另一种记录客户状态的机制,它在用户第一次打开浏览器连接到后端服务器时,由服务器创建产生,生成一个id号,作为会话标识.。

● 服务器通过Cookie将生成的会话id响应到浏览器中,之后每次请求将浏览器端的会话id向服务器端提交,服务器就可以得知是哪个客户端发起的请求。

session

会话:整个交互的过程。

session对象:服务器端记录会话信息的对象。

Servlet API中,定义了HttpSession接口,用来封装会话对象。

HttpSession是接口,会话对象是Web容器创建的,在Servlet中使用HttpServletRequest中的方法获得会话对象。

  • public HttpSession getSession():获取跟当前请求相关的session,如果不存在session,就创建一个新的session对象返回。

session生命周期:session对象,创建于前端连接到后端服务器开始。

销毁:1.服务器关闭

​ 2.非活动时间到期(多久不用,会自动销毁) Tomcat默认30分钟销毁

​ 3.退出,主动销毁session invalidate()

Cookie

Cookie中文译文是饼干的意思,cookie是保存会话数据的一种技术,其容量有 限;有生命周期,根据需求设置cookie有效期如果不进行设置的话,数据保存 至浏览器关闭。

Cookie中的信息存储在浏览器中,用于从服务器端向客户端响应一些相关数据.

Cookie coo = new Cookie(“key”, “value”);//创建一个键值对的cookie对象

coo.setMaxAge(606024*7);//设置cookie的生命周期

response.addCookie(coo);//添加到response中


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- 导入axios js包 -->
		<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function login(){
				var account = document.getElementById("accountid").value;
				var password = document.getElementById("passwordid").value;
				//表单验证
				 //return;
				//发起ajax请求   发起get(地址).then()  回调函数
				 /* axios.get("http://127.0.0.1:8888/webback/login?account="+account+"&password="+password)
				      .then(function(resp){
						  if(resp.data==0){
							   document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
						  }else if(resp.data==1){
							   document.getElementById("accountMsgId").innerHTML = "系统忙";
						  }else{
							  sessionStorage.setItem("id",resp.data.id);
							  sessionStorage.setItem("account",resp.data.account);
							  //location.replace("main.html");
						  }
					  }) */
					  axios.post(serverPath+"/login",
					             "account="+account+"&password="+password)
					             .then(function(resp){
					  						  if(resp.data==0){
					  							   document.getElementById("accountMsgId").innerHTML = "账号或密码错误";
					  						  }else if(resp.data==1){
					  							   document.getElementById("accountMsgId").innerHTML = "系统忙";
					  						  }else{
					  							  sessionStorage.setItem("id",resp.data.id);
					  							  sessionStorage.setItem("account",resp.data.account);
					  							  // location.replace("main.html");
					  						  }
					  					  }) 
			}
		</script>
	</head>
	<body>
		 
		<form>
			账号:<input type="text" name="account" value="" id="accountid"/> <br/>
			     <span id="accountMsgId"></span><br/>
			密码:<input type="password" name="password" id="passwordid"/><br/>
			    <input type="button" value="登录"  onclick="login()"/>
		</form>
		
	</body>
</html>
var serverPath = "http://127.0.0.1:8080/webback";
axios.defaults.withCredentials=true; //将浏览器中cookie中的sessionid向后端发送
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function showUserInfo(){
				var id = sessionStorage.getItem("id"); 
				var account = sessionStorage.getItem("account");
				if(account==null){
					location.replace("login.html");
					return;
				}
				document.getElementById("id").innerHTML=id;
				document.getElementById("accountid").innerHTML=account;
			}
			
			function test(){
				
				axios.get(serverPath+"/login").then(function(resp){});
			}
		</script>
	</head>
	<body onload="showUserInfo()">
		<!-- 登录成功之后,需要在此页面显示用户信息 -->
		<div>
			<span id="id"></span>
			<span id="accountid"></span>
			<input type="button" value="测试" onclick="test()" />
		</div>
	</body>
</html>

= “账号或密码错误”;
}else if(resp.data==1){
document.getElementById(“accountMsgId”).innerHTML = “系统忙”;
}else{
sessionStorage.setItem(“id”,resp.data.id);
sessionStorage.setItem(“account”,resp.data.account);
// location.replace(“main.html”);
}
})
}


	<form>
		账号:<input type="text" name="account" value="" id="accountid"/> <br/>
		     <span id="accountMsgId"></span><br/>
		密码:<input type="password" name="password" id="passwordid"/><br/>
		    <input type="button" value="登录"  onclick="login()"/>
	</form>
	
</body>
```
var serverPath = "http://127.0.0.1:8080/webback";
axios.defaults.withCredentials=true; //将浏览器中cookie中的sessionid向后端发送
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/axios.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			function showUserInfo(){
				var id = sessionStorage.getItem("id"); 
				var account = sessionStorage.getItem("account");
				if(account==null){
					location.replace("login.html");
					return;
				}
				document.getElementById("id").innerHTML=id;
				document.getElementById("accountid").innerHTML=account;
			}
			
			function test(){
				
				axios.get(serverPath+"/login").then(function(resp){});
			}
		</script>
	</head>
	<body onload="showUserInfo()">
		<!-- 登录成功之后,需要在此页面显示用户信息 -->
		<div>
			<span id="id"></span>
			<span id="accountid"></span>
			<input type="button" value="测试" onclick="test()" />
		</div>
	</body>
</html>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值