Web核心简介

 简介

web:全球广域网,也称万维网(www),能够通过浏览器访问的网站

JavaWeb:是用Java技术来解决相关web互联网领域的技术栈

JavaWeb技术栈

        B/S架构:Browser/Server,浏览器/服务器架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可

                好处:易于维护升级,服务器端升级后,客户端无需任何部署就可以使用到新的版本

静态资源:HTML、CSS、JavaScript、图片等。负责页面展现

动态资源:Servlet、JSP等。负责逻辑处理

数据库:负责存储数据

HTTP协议:定义通信规则

Web服务器:负责解析HTTP协议,解析请求数据,并发送响应数据

HTTP

         概念:HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则

        HTTP协议特点:

1. 基于TCP协议:面向连接,安全

2.基于请求-响应模型的:一次请求对应一次响应

3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。

        缺点:多次请求间不能共享数据

        优点:速度快

请求数据格式

格式

        请求数据分为3部分(如下图所示)

        1. 请求行:请求数据的第一行。其中GET表示请求方式(请求方式有7种,POST也是其中一种),/表示请求资源路径,HTTP/1.1表示协议版本

        2.请求头:第二行开始,格式为key : value形式。

        3.请求体:POST请求的最后一 部分,存放请求参数

常见的HTTP请求头

  • Host:表示请求的主机名
  • User-Agent:浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 ..Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT ... like Gecko
  • Accept:表示浏览器能接收的资源类型,如text/*、image/*或者*/*表示所有
  • Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页
  • Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip、deflate等

GET请求和POST请求区别

        GET请求请求参数在请求行中,没有请求体。POST请求请求参数在请求体中。

        GET请求请求参数大小有限制,POST没有

 

 相应数据格式

格式 

        响应数据分为3部分(如下图所示)

        1.响应行:响应数据的第一行。 其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述

        2.响应头:第二行开始,格式为key : value形式

        3.响应体:最后一部分。 存放响应数据

 响应状态码

状态码分类说明
1xx响应中--临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx成功--表示请求已经被成功接收, 处理已完成
3xx重定向一重定向到其它地方:它让客户端再发起一个请求以完成整个处理。
4xx客户端错误--处理发生错误, 责任在客户端,如:客户端的请求一个不存在的资源, 客户端末被授权,禁止访问等
5xx服务器端错误--处理发生错误, 责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

状态码大全:https://cloud.tencent.com/developer/chapter/13553

 *常见的相应状态码

状态码英文描述解释
200 OK客户端请求成功,即处理成功,这是我们最想看到的状态码
302Found指示所请求的资源已移动到由Location响应头给定的URL,浏览器会自动重新访问吧。隐式重定向
304Not Modified告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向
400Bad Request客户端请求有语法错误,不能被服务器所理解
403Forbidden服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源
404Not Found请求资源不存在,一般是URL输入有误,或者网站资源被删除了
428Precondition Required服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头
429Too Many Requests太多请求,可以限制客户端请求某个资源的数量,配合Retry-After(多长时间后可以请求)响应头一起使用
431Request Header Fields请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。
405Method Not Allowed请求方式有误,比如应该用GET请求方式的资源,用了POST
500Internal Server Error服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧
503Service Unavailable服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好
511Network Authentication Required客户端需要进行身份验证才能获得网络访问权限

常见的HTTP响应头

Content-Type:表示该响应内容的类型,例如text/htmI,image/jpeg

Content-Length:表示该响应内容的长度(字节数)

Content- Encoding:表示该响应压缩算法,例如gzip

Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒

Tomcat

Web服务器

        Web服务器是一个应该程序 (软件) ,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是“提供网上信息浏览服务”

        常见服务器软件:Tomcat、jetty、WebLogic、WebSphere

简介

        Tomcat是Apache软件基金会一个核心项目, 是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。

        JavaEE:Java Enterprise Edition, Java企业版。 指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、 EJB、 RMI、JSP、 Servlet、 XML、 JMS、 Java IDL、 JTS、JTA、 JavaMail、 JAF

        Tomcat也被称为Web容器、Servlet容器。 Servlet 需要依赖于Tomcat才能运行

        官网:https://tomcat.apache.org/

基本使用

        下载:官网下载

        安装:绿色版,直接解压即可

        卸载:直接卸载删除目录即可

        启动:双击bin\startup.bat

        配置:修改启动端口号:conf/server.xml

*HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号

        Tomcat部署项目:将项目放到webapps目录下,即部署完成

*一般JavaWeb项目会被打成war包,然后将war包放到webapps目录下,Tomcat会自动解压缩war文件

IDEA中创建Maven Web项目

Web项目结构

        Maven Web项目结构:开发中的项目

 

        部署的JavaWeb项目结构:开发完成,可以部署的项目

        编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下

        pom.xml中依赖坐标对应的jar包,放入WEB-INF下的Iib目录下

创建项目

        使用骨架 

        骨架:项目模板

  1. 选择web项目骨架,创建项目
  2. 删除pom.xml中多余的坐标
  3. 补齐缺失的目录结构

        不使用骨架

  1. 选择web项目骨架,创建项目
  2. pom.xml中添加打包方式为war
  3. 补齐缺失的目录结构: webapp

IDEA中使用Tomcat

        集成本地Tomcat:将本地Tomcat集成到Idea中,然后进行项目部署即可

        IDEA中使用Tomcat-Tomcat Maven插件:pom.xml添加Tomcat插件,使用Maven Helper插件快速启动项目,选中项目,右键--> Run Maven --> tomcat7:run

Servlet

        Servlet是Java提供的一门动态web资源开发技术

        Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet

快速入门

        1.创建web项目,导入Servlet依赖坐标

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

        2.创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话

        3.配置:在类上使用@WebServlet注解,配置该Servlet的访问路径

@WebServlet("/study")
public class StudyServlet implements Servlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("hello");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

        4.访问:启动Tomcat,浏览器输入URL访问该Servlet

Servlet执行流程

        Servlet由web服务器创建,Servlet方法由web服务器调用。

Servlet生命周期

        对象的生命周期指一个对象从被创建到被销毁的整个过程

        Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段

        1.加载和实例化:默认情况下,当Servlet第一 次被访问时, 由容器创建Servlet对象              2.初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象, 完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

        3. 请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理。

        4.服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后, 容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

* 可以通过配置参数设置对象创建的时机

@WebServlet(value = "/study", loadOnStartup = 1)
//负整数:第一次被访问时创建Servlet对象
//0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高

*Servlet方法

        初始化方法,在Servlet被创建时执行,只执行一次

void init(ServletConfig config)

        提供服务方法,每次Servlet被访问, 都会调用该方法

void service(ServletRequest req, ServletResponse res)

        销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet

void destroy()

        获取ServletConfig对象

ServletConfig getServletConfig()

        获取Servlet信息(比如作者、版本、版权)

String getServletlnfo()

Servlet体系结构

        开发B/S架构的web项目,都是针对HTTP协议,所以自定义Servlet会继承HttpServlet。

        HttpServlet使用步骤:继承HttpServlet,重写doGet和doPost方法

        HttpServlet原理:获取请求方式,并根据不同的请求方式,调用不同的doXxx方法

@WebServlet("/pro")
public class ServletPro extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post");
    }
}

urlPattern配置

        Servlet要想被访问,必须配置其访问路径(urlPattern) 

         一个Servlet,可以配置多个urlPattern

@WebServLet(urlPatterns = {"/demo1", "/demo2"})

        urlPattern配置规则:精确匹配、目录匹配、扩展名匹配、任意匹配

精确匹配

        配置路径:@WebServle("/user/aaa")

        访问路径:localhost:8080/study/user/aaa

目录匹配(当与精确匹配相同时,优先精确匹配)

        配置路径:@WebServle("/user/*")

        访问路径:localhost:8080/study/user/aaa

                          localhost:8080/study/user/bbb

扩展名匹配(路径不能以 / 开头)

        配置路径:@WebServle("*.txt")

        访问路径:localhost:8080/study/user/aaa.txt

                          localhost:8080/study/user/bbb.txt

任意匹配(/* 优先级高于 /)

        配置路径:@WebServle("/")  

                          @WebServle("/*")

        访问路径:localhost:8080/study/user/aaa

                          localhost:8080/study/user/bbb

/ 和 /* 区别:

        当我们的项目中的Servlet配置了"/" ,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet

        当我们的项目中配置了 /*,意味着匹配任意访问路径

        优先级:精确路径 > 目录路径 > 扩展名路径 > /* > /

XML配置方式

        Servlet从3.0版本后开始支持使用注解配置,3.0版本前只支持XML配置文件的配置方式

         步骤:1. 编写Servlet类 2.在web.xml中配置该Servlet

<!--配置全类名-->
<servLet>
    <servlet-name>study</servLet-name>
    <servlet-class>com.GLATY.web.servLet.StudyServlet</servLet-class> 
</servlet>

<!--Servlet访问路径-->
<servLet -mapping>
    <servLet-name>study</servLet-name>
    <urL-pattern>/study</url-pattern>
</servLet-mapping>

Request

        获取请求数据

继承体系

        Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中

        使用request对象,查阅JavaEE API文档的HttpServletRequest接口

获取请求数据

        请求数据分为3部分:请求行、请求头、请求体

请求行:

GET/request-demg/req1?username=zhangsan HTTP/1.1

方法介绍
String getMethod()获取请求方式:GET
String getContextPath()获取虚拟目录(项目访问路径):/request-demo
StringBuffer getRequestURL()获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
String getRequestURI()获取URl(统以资源标识符): /request-demo/req1
String getQueryString()获取请求参数(GET方式):username= zhangsan&password=123
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取请求行数据
    System.out.println(req.getMethod());
    System.out.println(req.getContextPath());
    System.out.println(req.getRequestURL());
    System.out.println(req.getRequestURI());
    System.out.println(req.getQueryString());
}

请求头:

User-Agent: Mozilla/5.0 Chrome/91.0.4472.106

方法介绍
String getHeader(String name)根据请求头名称,获取值
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取请求头数据;user-agent:浏览器的版本信息
    System.out.println(req.getHeader("user-agent"));
}

请求体:

username=superbaby&password=123

方法介绍
ServletInputStream getInputStream()获取字节输入流
BufferedReader getReader()获取字符输入流
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取post请求体
    
    //获取流
    BufferedReader br = req.getReader();
    //读取数据
    System.out.println(br.readLine());
}

 使用通用方式获取请求参数

方法介绍
Map<String, String[ ]> getParameterMap()获取所有参数Map集合
String[ ] getParameterValues(String niame)根据名称获取参数值(数组)
String getParameter(String name)根据名称获取参数值(单个值)

         这样写代码时如果通过get和post要进行的操作一样,可以减少重复的代码(如下)

@WebServlet("/pro3")
public class StudyServlet3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map<String, String[]> map = req.getParameterMap();
        for (String temp : map.keySet()) {
            String[] out = map.get(temp);
            for (String out0 : out) {
                System.out.print(out0 + " ");
            }
        }
    }

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

 请求参数中文乱码处理

        请求参数如果存在中文数据,则会乱码。原因是因为tomcat进行URL解码时用的是字符集ISO-8859-1

        如果是post只需要在获取数据前设置字符输入流的编码为UTF-8即可(字符输入流的编码默认为)。

方法介绍
setCharacterEncoding("") ;设置字符输入流的编码
req.setCharacterEncoding("UTF-8");

        如果是get,可以先将数据转换成字节数据,然后再转为字符串即可(该方法也适用于post)

byte[] bys = out0.getBytes(StandardCharsets.ISO_8859_1); //StandardCharsets.ISO_8859_1 也课写为"ISO-8859-1"
String str = new String(bys, StandardCharsets.UTF_8);

        Tomcat8.0之后,已经将GET请求乱码问题解决,设置默认的解码方式为UTF-8 

请求转发

        请求转发(forward):一种在服务器内部的资源跳转方式

实现方式:

req.getRequestDispatcher("资源B路径' ').forward(req, resp);

请求转发资源间共享数据:使用Request对象

方法介绍
void setAttribute(String name, Object o)存储数据到request域中
Object getAttribute(String name)根据key,获取值
void removeAttribute(String name)根据key,删除该键值对

请求转发特点:

  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器的内部资源
  • 一次请求, 可以在转发的资源间使用request共享数据

Response

        设置响应数据

设置相应数据功能介绍

响应数据分为3部分:

1.响应行:HTTP/1.1 200 OK

方法介绍
void setStatus(int sc)设置响应状态码

2. 响应头:Content-Type: text/html

方法介绍
void setHeader(String name, String value)设置响应头键值对

3. 响应体:<html><head>head><body></body></html>

方法介绍
PrintWriter getWriter()获取字符输出流
ServletOutputStream getOutputStream()获取字节输出流

重定向

        重定向(Redirect):一种资源跳转方式

实现方式:先设置相应状态码302,然后设置响应头location

resp. setStatus (302);

resp. setHeader( " location",''另一个资源的路径");

resp.setStatus(302);
resp.setHeader("location", "/studyServlet/study");

简化方式:

resp. sendRedirect(''另一个资源的路径");

resp.sendRedirect("/studyServlet/study");

重定向特点:

  • 浏览器地址栏路径发生变化
  • 可以重定向到任意位置的资源(服务器内部、外部均可)
  • 两次请求,不能在多个资源使用request共享数据

路径问题

        浏览器使用:需要加虚拟目录(项目访问路径)

        服务端使用:不需要加虚拟目录

动态获取虚拟目录:

String context = req.getContextPath();

String context = req.getContextPath();
resp.sendRedirect(context + "/study");

响应字符数据

        1.通过Response对象获取字符输出流

PrintWriter writer = resp.getWriter();

        2.写数据

writer.write("内容");

resp.setHeader("content-type", "text/html");//告诉浏览器这是HTML文本,默认是纯文本
PrintWriter writer = resp.getWriter();
writer.write("<h1>abc</h1>");

        写数据默认用的是ISO-8859-1而不是UTF-8,如果要输入汉语需要更换格式

resp.setContentType("text/html;charset=utf-8");//告诉浏览器这是HTML文本,并设置使用UTF-8字符集写数据
PrintWriter writer = resp.getWriter();
writer.write("<h1>你好</h1>");

响应字节数据

        1.通过Response对象获取字符输出流

ServletOutputStream outputStream = resp.getOutputStream();

        2.写数据

outputStream.write(字节数据);

IOUtils工具类使用

        1.导入坐标

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.9.0</version>
</dependency>

        2.使用

IOUtils.copy(输入流, 输出流);

FileInputStream fis = new FileInputStream("src/main/webapp/a.jpg");
ServletOutputStream os = resp.getOutputStream();
IOUtils.copy(fis, os);  //导包时要导apache的

JSP

        概念:Java Server Pages, Java服务端页面

        一种动态的网页技术,其中既可以定义HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容

        JSP = HTML+Java

        JSP的作用:简化开发,避免了在Servlet中直接输出HTML标签

快速入门

导坐标

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

建文件

        在webapp目录下创建jsp文件

写标签代码

<body>
    <h1>Hello</h1>
    <% System.out.println("^_^");%>
</body>

原理

        JSP本质上是一个Servlet4

        JSP在被访问时,由JSP容器(Tomcat)将其转换为Java文件(Servlet),在由JSP容器(Tomcat)将其编译,最终对外提供服务的其实就是这个字节码文件

脚本

        JSP脚本用于在JSP页面内定义Java代码

JSP脚本分类:

  1. <%...%>:内容会直接放到_jspService()方法之中
  2. <%=...%>:内容会放到out.print()中, 作为out.print()的参数
  3. <%!...%>:内容会放到_jspService()方法之外,被类直接包含

缺点

由于JSP页面内,既可以定义HTML标签,又可以定义Java代码,造成了以下问题:

  1. 书写麻烦:特别是复杂的页面
  2. 阅读麻烦
  3. 复杂度高:运行需要依赖于各种环境, JRE, JSP容器,JavaEE...
  4. 占内存和磁盘:JSP会自动生成java和.class文件占磁盘,运行的是.class文件占内存
  5. 调试困难:出错后,需要找到自动生成的.java文件进行调试
  6. 不利于团队协作:前端人员不会Java,后端人员不精HTML
  7. ...

EL表达式

        Expression Language表达式语言,用于简化JSP页面内的Java代码

        主要功能:获取数据

        语法: ${expression}

${things}

获取域中存储的key为brands的数据

先写Java代码 

@WebServlet("/pro4")
public class StudyServlet4 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //准备数据
        List<Thing> things = new ArrayList<>();
        things.add(new Thing("name1", 1));
        things.add(new Thing("name2", 2));
        things.add(new Thing("name3", 3));
        
        //存储到request域中
        req.setAttribute("things", things);
        
        //转发到jsp文件中
        req.getRequestDispatcher("study.jsp");
    }

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

JavaWeb中的四大域对象:

  1. page:当前页面有效
  2. request:当前请求有效
  3. session:当前会话有效
  4. application:当前应用有效

el表达式获取数据,会依次从这4个域中寻找,直到找到为止

JSTL标签

        JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码

快速入门

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>  <%--prefix后的属性可以任意填写,一般写c--%>
<html>
<head>
    <title>Title</title>
</head>
<body>
</body>
</html>

if标签

        用来完成逻辑判断,替换Java  if else

<c:if test="true">  <%--如果test的值为true则会显示标签内的内容,如果为false则不显示--%>
    <h1>true</h1>
</c:if>
forEach标签

forEach标签

        forEach相当于for循环

                items:被遍历的容器

                var:遍历产生的临时变量

                varStatus:遍历状态对象(index从0开始,count从1开始)

                begin:开始数

                end:结束数

                step:步长

<c:forEach items="${things}" var="Thing">
    <tr align="center">
        <td>${Thing.id}</td>
        <td>${Thing.name}</td>
    </tr>
</c:forEach>

<c:forEach begin="0" end="2" step="1" var="i">
    ${i}
</c:forEach>

MVC模式和三层架构

MVC

        MVC是一种分层开发的模式, 其中:

M:Model, 业务模型,处理业务

V:View,视图,界面展示

C:Controller,控制器,处理请求,调用模型和视图

        MVC好处:

职责单一,互不影响

有利于分工协作

有利于组件重用

 三层架构

        数据访问层:对数据库的CRUD基本操作

        业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能

        表现层:接收请求,封装数据,调用业务逻辑层,响应数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值