JavaWeb入门到实战

1.基本概念

1.1前言

Java Web,是用Java技术来解决相关web互联网领域的技术栈。web包括:web服务端和web客户端两部分。Java在客户端的应用有java applet,不过使用得很少,Java在服务器端的应用非常的丰富,比如Servlet,JSP和第三方框架等等。Java技术对Web领域的发展注入了强大的动力。

1.2web应用程序

可以提供浏览器访问的程序;

  1. a.html、b.html.….多个web资源,这些web资源可以被外界访问,对外界提供服务;
  2. 你们能访问到的任何一个页面或者资源,都存在于这个世界的某一个角落的计算机上。
  3. URL
  4. 这个统一的web资源会被放在同一个文件夹下,web应用程序>Tomcat:服务器、
  5. 一个web应用由多部分组成(静态web,动态web)
    • html,css
    • jsp,servlet
    • Java程序
    • jar包
    • 配置文件(Properties)

Web应用程序编写完毕后,若想提供给外界访问;需费一个服务器来统一管理。

1.3静态web

静态网站特点:

  1. 静态网站是最初的建站方式,浏览者所看到的每个页面是建站者上传到服务器上的一个 html ( htm )文件,这种网站每增加、删除、修改一个页面,都必须重新对服务器的文件进行一次下载上传。网页内容一经发布到网站服务器上,无论是否有用户访问,每个静态网页的内容都是保存在网站服务器上的,也就是说,静态网页是实实在在保存在服务器上的文件,每个网页都是一个独立的文件;
  2. 静态网页的内容相对稳定,因此容易被搜索引擎检索;
  3. 静态网页没有数据库的支持,在网站制作和维护方面工作量较大,因此当网站信息量很大时完全依靠静态网页制作方式比较困难;
  4. 静态网页的交互性较差,在功能方面有较大的限制。如:不能实现用户注册和用户登录的功能

静态web原理图如下图所示:

image-20220318093048633

1.4动态web

所谓 “ 动态 ” ,并不是指网页上简单的 GIF 动态图片或是 Flash 动画,动态网站的概念现在还没有统一标准,但都具备以下几个基本特征:

  1. 交互性:网页会根据用户的要求和选择而动态地改变和响应,浏览器作为客户端,成为一个动态交流的桥梁,动态网页的交互性也是今后 Web 发展的潮流。
  2. 自动更新:即无须手动更新 HTML 文档,便会自动生成新页面,可以大大节省工作量。
  3. 因时因人而变:即当不同时间、不同用户访问同一网址时会出现不同页面。

动态web原理图如下图所示:

image-20220318093200544

2.Tomcat

2.1 Tomcat文件夹信息

image-20220318093820499

2.2 核心配置文件

image-20220318094542925

可以配置启动的端口号

  • tomcat的默认端口号为:8080
  • http:80 https: 443
  <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

可以配置主机的名称

  • 默认的主机名为: localhost->127.0.0.1
  • 默认网站应用存放的位置为:webapps
 <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

可以在这修改访问地址:

​ C:\Windows\System32\drivers\etc/hosts

image-20220318095321709

高难度面试题:

请你谈谈网站是如何进行访问的?

1.输入一个域名,回车

2.检查本机的 C:\Windows\System32\drivers\etc/hosts 配置文件下有没有这个域名映射;

1.有: 直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接方法

127.0.0.1       www.jihu.com

2.没有 : 去DNS服务器找,找到的话就返回,找不到就返回找不到;

image-20220318100125654

2.3发布一个web网站

将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了

--webapps :Tomcat服务器的web目录
	-ROOT
	-jihu :网站的目录名
		- WEB-INF
			-classes : java程序
			-lib:web应用所依赖的jar包
			-web.xml :网站配置文件
		- index.html 默认的首页
		- static 
            -css
            	-style.css
            -js
            -img
         -.....

3.Http

3.1Http简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。

image-20220318103050489

3.2主要特点

1、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

4.无状态:所谓http是无状态协议,言外之意是说http协议没法保存客户机信息,也就没法区分每次请求的不同之处。关于http无状态阻碍了交互式应用程序的实现。比如记录用户浏览哪些网页、判断用户是否拥有权限访问等。于是,两种用于保持HTTP状态的技术就应运而生了,一个是Cookie,而另一个则是Session。
5、支持B/S及C/S模式。

3.3HTTP值URL

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的URI(URL则通过描述是哪个主机上哪个路径上的文件来唯一确定一个资源,也就是定位的方式来实现的URI),URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。以下面这个URL为例,介绍下普通URL的各部分组成:

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

从上面的URL可以看出,一个完整的URL包括以下几部分:
1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在”HTTP”后面的“//”为分隔符

2.域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用

3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口

4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”

5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名

6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分

7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

3.4Http请求

客户端发送请求(Request)给服务器

以向百度发起请求为例:

Request URL:https://www.baidu.com/   请求地址
Request Method:GET    get方法/post方法
Status Code:200 OK    状态码:200
Remote(远程) Address:14.215.177.39:443
Accept:text/html  
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9    语言
Cache-Control:max-age=0
Connection:keep-alive

1.请求行

  • 请求行中的请求方式:GET
  • 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
    • get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
    • post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。

2.请求头

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.

3.5Http响应

  • 服务器发出响应给客户端

以百度为例

Cache-Control:private    缓存控制
Connection:Keep-Alive    连接
Content-Encoding:gzip    编码
Content-Type:text/html   类型

1.响应体

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;

2.响应状态码

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

1xx:指示信息–表示请求已接收,继续处理

2xx:成功–表示请求已被成功接收、理解、接受

3xx:重定向–要完成请求必须进行更进一步的操作

4xx:客户端错误–请求有语法错误或请求无法实现

5xx:服务器端错误–服务器未能实现合法的请求

常见状态码:

200 OK                        //客户端请求成功
400 Bad Request               //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized              //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 
403 Forbidden                 //服务器收到请求,但是拒绝提供服务
404 Not Found                 //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error     //服务器发生不可预期的错误
503 Server Unavailable        //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

其他部分请参考链接: http协议一篇就够了

3.6 Get和Post的区别

  • GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.

  • GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

  • GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。

  • GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.

4.Maven

4.1 maven简介

Maven是一个采用纯Java编写的开源项目管理工具。Maven采用了一种被称之为project object model (POM)概念来管理项目,所有的项目配置信息都被定义在一个叫做POM.xml的文件中,通过该文件,Maven可以管理项目的整个声明周期,包括编译,构建,测试,发布,报告等等。目前Apache下绝大多数项目都已经采用Maven进行管理。而Maven本身还支持多种插件,可以方便更灵活的控制项目。一句话:Maven是一个项目管理和构建工具,主要做编译、测试、报告、打包、部署等操作完成项目的构建。Maven不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了中央仓库,能帮我自动下载构件。

4.2 下载安装maven

maven官网:https://www.apache.org

image-20220318113909907

下载完毕后,解压即可;

4.3 配置环境变量

在系统变量中添加 M2_HOME

image-20220318111508800

在系统变量的path中添加 %M2_HOME%\bin

image-20220318111528107

测试Maven环境是否按装成功,保证必须配置完毕

image-20220318111726479

4.4 配置阿里云镜像和本地仓库

配置镜像(镜像(Mirroring)是一种文件存储形式,是冗余的一种类型,一个磁盘上的数据在另一个磁盘上存在一个完全相同的副本即为镜像。),使用默认仓库下载jar包会比较慢,所以配置一个阿里云镜像

打开maven安装目录下的conf\settings.xml 添加如下信息

<mirrors>
	<mirror>
          <id>nexus-aliyun</id>
          <mirrorOf>central</mirrorOf>
          <name>Nexus aliyun</name>
          <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
	</mirror>
</mirrors>

添加本地仓库路径:

<localRepository>D:\222\abo\repository</localRepository>

image-20220318112830443

4.5 pom.xml的结构

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>ch07-spring-mybatis</artifactId>
  <version>1.0-SNAPSHOT</version>



  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
  <!--单元测试   -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <!--目的是吧src/main/java目录中的xml文件包含到输出结果中。 输出到classes目录中 -->
    <resources>
      <resource>
        <directory>src/main/java</directory>  <!--所在目标-->
        <includes>  <!--包括目录下的.properties, .xml文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
    <!--指定jdk的版本-->
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>

  </build>
</project>

4.6web.xml中webapp版本问题

自动生成的webapp是2.3版本的,最新版的版本在tomcat中可以找到

<?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"
         metadata-complete="true">
</web-app>

5.Servlet

Pom.xml

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2.1-b03</version>
</dependency>

6.Cookie 、Session

6.1会话

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;

一个网站,怎么证明你来过?

客户端 服务端

  1. 服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie
  2. 服务器登记你来过了,下次你来的时候我来匹配你; seesion

6.2 保存会话的两种技术

cookie

  • 客户端技术 (响应,请求)

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息? 我们可以把信息或者数据放在Session中!

常见常见:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!

6.3Cookie

1.由服务器创建一个cookie,并设置数据和属性,再由服务器发送给客户端,客户端在本地保存该cookie

2.下次访问时带上该cookie,服务器就能知道你先前来过,并可以通过cookie获取数据2.

Cookie[] cookies = req.getCookies(); //获得cookie
cookie.getName()  //获得cookie中的key
cookie.getValue()  //获得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis() + "");  //新建一个cookie
cookie.setMaxAge(24*60*60);  //cookie的有效期为一天
resp.addCookie(cookie);  //响应给客户端一个cookie

cookie:一般会保存在本地的 用户目录下 appdata;

删除cookie

  • 不设置有效期,关闭浏览器,自动失效

  • 设置有效期时间为0

cookie中解决字符串乱码的问题

//编码
Cookie cookie1 = new Cookie("name", URLEncoder.encode("张三", "utf-8"));
//解码
 out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));

例子

package com.jihu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;

//保存用户上一次访问的时间
public class CookieDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下次带来,我就知道你来了

        //解决中文乱码
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");

        PrintWriter out = resp.getWriter();

        //cookie,服务器端从客户端获取的
        Cookie[] cookies = req.getCookies();  //这里返回数组,说明cookie可能存在多个

        //判断cookie是否存在
        if (cookies != null){
            //如果存在
            out.write("你上一次访问的时间是:");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("lastLoginTime")){
                    //获取cookie的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                    //out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
                }
            }

        }else{
            out.write("这是您第一次访问本站");
        }

        //服务给客户端响应一个cookie

        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
        //Cookie cookie1 = new Cookie("name", URLEncoder.encode("张三", "utf-8"));
        //cookie的有效期为一天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

6.4 Session (重点)

什么是session:

  • 服务器会给每一个用户(浏览器)创建一个session对象;
  • 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在;
  • 用户登录之后,整个网站它都可以访问! –> 保存用户的信息保存购物车的信息

例子

SessionDemo01

public class SessionDemo01 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到session
        HttpSession session = req.getSession();

        //给session中存东西
        //session.setAttribute("name","张二哈");
        session.setAttribute("name",new Person("二哈",20));

        //获取session的id
        String sessionId = session.getId();

        //判断session是不是新创建
        if (session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

SessionDemo02

public class SessionDemo02 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到session
        HttpSession session = req.getSession();
        //String name = (String) session.getAttribute("name");
        Person name = (Person) session.getAttribute("name");
        //System.out.println(name);
        System.out.println(name.toString());
        PrintWriter out = resp.getWriter();
        out.println(name);
        out.flush();
        out.close();
    }
}    

SessionDemo03(手动注销session)

public class SessionDemo03  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手动注销session
        session.invalidate();
    }
}    

删除session

session的存活时间可以在web.xml中进行配置

<!--设置session默认的失效时间-->
<session-config>
    <!--15分钟后session自动失效,以分钟为单位-->
    <session-timeout>1</session-timeout>
</session-config>

6.5 cookie和seesion的相同点和不同点

相同的:

cookie和session都是为了解决http协议无状态的特征

区别:

  1. cookie数据是存放在客户端本地的,session数据是存放在服务器的,但是服务端的session的实现对客户端的cookie有依赖关系的;

  2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session;

  3. session会在一段时间内存放在服务器,如果session过多,会导致服务器压力过大,性能降低。如果考虑服务器性能方面应该使用cookie

  4. cookie的大小是有限制的

  5. 一个用户在一个站点上可以有多个cookie,但是只有一个session

  6. session对象由服务创建