JavaWeb

2023-05-16

JavaWeb

Java. web

1. 基本概念

1.1 前言

web开发:

  • web:网页的意思 www.baidu.com

  • 静态web

    • html. Css
    • 提供给所有人看的数据始终不会发生变化!
  • 动态web

    • 淘宝等,几乎是所有的网站!

    • 提供给所有人看的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同!

    • 技术栈:Servlet/JSP,ASP,PHP

在java中,动态web资源开发的技术统称为JavaWeb

1.2 web应用程序

web应用程序:可以提供浏览器访问的程序;

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

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

1.3 静态web

  • *.htm , *.html 这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取,(网络);

  • 静态web存在的缺点:

    • web页面无法动态更新,所有用户看到的都是同一个页面

    • 轮播图,点击特效:伪动态

    • javaScript(实际开发中用的多)

    • VBScript

    • 它无法和数据库交互(数据无法持久化,用户无法交互)

1.4 动态web

页面会动态展示:“web展示的效果因人而异!”

缺点:

  • 假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布;
    • 重新发布=停机维护

优点:

  • web页面可以动态更新,所有用户看到的都不是同一个页面

  • 它可以和数据库交互(数据可以持久化:注册,商品信息可以存在数据库…,用户可以交互)

2、web服务器

2.1、技术讲解

ASP:

  • 微软:国内最早流行的就是ASP
  • 在html中嵌入了VB的脚本:ASP+DOM;
  • 在ASP开发中,基本一个页面都有几千行的业务代码,页面极其混乱(html和java写在一起)
  • 维护成本高!
  • C#
  • IIS

PHP

  • PHP开发速度很快,功能很强大,跨平台,代码很简单(70%,WP)
  • 无法承载大访问量的情况(局限性)

JSP/Servlet:

B/S:浏览器和服务器

C/S:客户端和服务器

  • sun公司主推的B/S架构
  • 基于java语言的(所有的大公司,或者一些开源的组件,都是用Java写的)
  • 可以承载三高问题带来的影响;
  • 语法像ASP,方便ASP转JSP,加强市场强度;

2.2、web服务器

服务器是一种被动的操作,用来处理用户的请求和给用户一些响应信息;

iis:

微软的;ASP,,windows中自带

Tomcat:

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,他是最佳的选择。

而Tomcat 实际上运行JSP 页面和Servlet。目前Tomcat最新版本为9.0.30。

3、Tomcat

3.1、Tomcat官网

https://tomcat.apache.org

3.2、Tomcat的启动和配置

启动Tomcat: /Users/mac/Library/tomcat/bin/startup.sh

关闭Tomcat: /Users/mac/Library/tomcat/bin/shutdown.sh

可能遇到的问题:

  1. java环境变量没有配置
  2. 闪退问题:
  3. 乱码问题:

3.3、配置

可以配置启动的端口号;

  • tomcat的默认端口号:8080

  • mysql:3306

  • http:80

  • https:443

可以配置主机的名称:

  • 默认的主机名为:localhost–>127.0.0.1
  • 默认网站应用存放的位置为:webapps

高难度面试题

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

  1. 输入一个域名:回车
  2. 检查本机的hosts配置文件下有没有这个域名的映射;
    1. 有:直接返回对应的ip地址,这个地址中有我们需要访问的web程序,可以直接访问
    2. 没有:去DNS(全世界的域名都在这里管理)服务器找,找到的话就返回找到,找不到就返回找不到…

3.4、发布一个web网站

不会就先模仿!

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

  • 网站应有的结构:

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

HTTP协议:面试

Maven:构建工具

  • maven安装包

Servlet入门

  • HelloWorld
  • Severlet配置
  • 原理

4、Http

4.1 什么是Http

http(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。

  • 文本:html,字符串,,,,
  • 超文本:图片,音乐,视频,定位,地图。。。
  • 默认端口:80

Https:(加密)

  • 默认端口:443

4.2、两个时代

  • Http1.0
    • HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接。
  • Http2.0
    • HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。

4.3、Http请求

  • 客户端–>发请求(Request)–>服务器

    Request URL:https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/home/js/nu_instant_search_baaa58d.js   //请求地址
    Request Method: GET   //get方法/post方法
    Status Code: 200  (from memory cache)  //状态码:200
    Remote(远程) Address: 183.201.233.32:443  //
    
    :authority: dss3.baidu.com
    :method: GET
    :path: /-rVXeDTa2gU2pMbgoY3K/it/u=701675230,3439008724&fm=202&mola=new&crop=v1
    :scheme: https
    accept: image/webp,image/apng,image/*,*/*;q=0.8
    accept-encoding: gzip, deflate, br
    accept-language: zh-CN,zh;q=0.9
    cookie: BIDUPSID=25FC099492B03BC6D724B99139BE7C00; PSTM=1574690755; BAIDUID=25FC099492B03BC6B769B03C4B7F8EF7:FG=1; delPer=0; H_PS_PSSID=1454_21108_30211_30283_26350_22157; PSINO=1
    referer: https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=java&rsv_pq=a7b71db0000a86e7&rsv_t=d954LlVjnwQ%2F%2BDdfHsZNPH%2FZwioIqTxTYlQFPza0gJLxtdOChA9trFVS%2BbA&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_sug3=5&rsv_sug1=3&rsv_sug7=101&rsv_sug2=0&inputT=1681&rsv_sug4=2717
    sec-fetch-mode: no-cors
    sec-fetch-site: same-site
    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
    

    1、请求行

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

    2、消息头

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

4.4、Http响应

  • 服务器–>发请求–>客户端
cache-control: max-age=315360000  //缓存控制
Connection:keep-Alive  //连接
content-encoding: gzip    //编码
Content-Type:text/html   //类型

1、响应体

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

2、响应状态码

200:请求响应成功。200

3xx:请求重定向

  • 重定向:你重新到我指定的新位置;

4xx:找不到资源。404

  • 资源不存在

5xx:服务器代码错误。500

502:网关错误

常见面试题:

当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?

5、Maven

我为什么要学习这个技术?

  1. 在Javaweb中,需要使用大量的jar包,我们需要手动导入;

  2. 如何能够让一个东西能够帮我们自动导入和配置这个jar包;

    由此,Maven诞生!

5.1、Maven项目架构管理工具

我们目前用它来就是方便导入jar包的!

Maven的核心思想:约定大于配置

  • 有约束,不要去违反

Maven会规定好你该如何去编写我们的Java代码,必须按这个规范来

5.2、Maven下载

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

安装和配置请自行百度

maven由于他的约定大于配置,我们之后可能遇到我们写的配置文件,无法导出或者生效问题,解决方案:

//在build中配置resource,来防止资源导出失败的问题
<build>  
    <finalName>test</finalName>  
    <!--  
    这样也可以把所有的xml文件,打包到相应位置。  
    <resources>  
        <resource>  
            <directory>src/main/resources</directory>  
            <includes>  
                <include>**/*.properties</include>  
                <include>**/*.xml</include>  
                <include>**/*.tld</include>  
            </includes>  
            <filtering>false</filtering>  
        </resource>  
        <resource>  
            <directory>src/main/java</directory>  
            <includes>  
                <include>**/*.properties</include>  
                <include>**/*.xml</include>  
                <include>**/*.tld</include>  
            </includes>  
            <filtering>false</filtering>  
        </resource>  
    </resources>  
</build>  

6、Servlet

6.1 servlet简介

  • Servlet就是sun公司开发动态web的一门技术
  • sun公司在这些API中提供了一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • 编写一个类,实现Servlet接口
    • 把开发好的java类部署到web服务器中

把实现了Servlet接口的Java程序,叫做Servlet

6.2、HelloServlet

Servlet接口在Sun公司有两个默认的实现类:HttpServlet、GenericServlet

  1. 构建一个普通的maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Model;这个空的工程就叫做Maven的主工程

  2. 关于Maven父子工程的理解:

    父项目中会有:

     <modules>
            <module>Servlet-02</module>
        </modules>
    

    子项目中会有:

    		<parent>
            <artifactId>javaweb-02-Servlet</artifactId>
            <groupId>com.yuan</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
    

    父项目中的jar包,子项目可以直接使用

    son extends father//类似于java的多态
    
    1. Maven环境优化

      1. 修改web.xml为最新的
      2. 将Maven的结构搭建完整
    2. 编写一个Servlet程序

      1. 编写一个普通类

      2. 实现Servlet接口,这里我们直接继承HttpServlet

        public class HelloServlet extends HttpServlet {
        
            //由于get或者post只是请求实现的不同方式,可以相互调用,业务逻辑都一样
        
        
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                //ServletOutputStream outputStream = resp.getOutputStream();
                PrintWriter writer = resp.getWriter();//响应流
                writer.println("Hello Servlet");
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                super.doPost(req, resp);
            }
        }
        
        
    3. 编写Servlet的映射

      为什么需要映射:我们写的是java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径;

    4. 配置Tomcat

      注意:配置项目的发布路径就可以了

    5. 启动测试

6.3、Servlet原理

Servlet是由web服务器调用,web服务器在收到浏览器请求之后,进行一系列转化…用到service方法…

我们自己编写的实现类,重写这些方法:

  1. 接收并处理请求
  2. 给出响应的信息

6.4、Mapping问题

  1. 一个Servlet请求可以指定一个映射路径

    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello</url-pattern>
    </servlet-mapping>	
    
  2. 一个Servlet请求可以指定多个映射路径

    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello</url-pattern>
    </servlet-mapping>	
    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello1</url-pattern>
    </servlet-mapping>	
    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello2</url-pattern>
    </servlet-mapping>	
    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello3</url-pattern>
    </servlet-mapping>	
    
  3. 一个Servlet请求可以指定通用映射路径

    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>	
    
  4. 默认请求路径(会把首页给覆盖)

    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>/*</url-pattern>
    </servlet-mapping>	
    
  5. 指定一些后缀或者前缀等等…

    <servlet-mapping>
    	<servlet-name>hello</servlet-name>
      <url-pattern>*.do</url-pattern>  //*前面不能加映射的路径"/" 
    </servlet-mapping>	
    
    1. 优先级问题:

    指定了固有的映射路径优先级最高,如果找不到就会去走默认的处理请求;

//404
<servlet>
	<servlet-name>error</servlet-name>
  <url-pattern>com.yuan.servlet.ErrorServlet</url-pattern>  //*前面不能加映射的路径"/" 
</servlet>	
<servlet-mapping>
	<servlet-name>error</servlet-name>
  <url-pattern>/*</url-pattern>  //*前面不能加映射的路径"/" 
</servlet-mapping>	

6.5、ServletContext

1.1. 介绍

ServletContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。

img

1.2. 作用

  1.  是一个域对象
    
  2.  可以读取全局配置参数
    
  3.  可以搜索当前工程目录下面的资源文件
    
  4.  可以获取当前工程名字(了解)
    

1.2.1. servletContext是一个域对象

1.2.1.1. 域对象介绍

     域对象是服务器在内存上创建的存储空间,用于在不同动态资源(servlet)之间传递与共享数据。

1.2.1.2. 域对象方法

凡是域对象都有如下3个方法:

setAttribute(name,value);//name是String类型,value是Object类型;   往域对象里面添加数据,添加时以key-value形式添加
getAttribute(name);  //根据指定的key读取域对象里面的数据
removeAttribute(name);  //根据指定的key从域对象里面删除数据

1.2.1.3. 域对象功能代码

域对象存储数据AddDataServlet代码

/**
      * doGet
      */
     publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
         //往serlvetContext里面存数据
        
         //1.获取ServletContext对象
         //getServletContext()
         //2.往对象里面设置数据
         getServletContext().setAttribute("username", "admin");
        
         response.getOutputStream().write("用户名写入到servletContext成功".getBytes());
     }
————————————————

原文链接:https://blog.csdn.net/qq_36371449/article/details/80314024

获取域对象数据GetDataServlet代码

/**
      * doGet
      */
     publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
        
         //获取ServletContext里面的用户名数据
         Object valueObject = getServletContext().getAttribute("username");
         if(valueObject!=null){
              response.getOutputStream().write(("从servletContext读取到的用户名数据:"+valueObject.toString()).getBytes());
         }
 
     }
————————————————
原文链接:https://blog.csdn.net/qq_36371449/article/details/80314024

servletContext存储数据特点:

全局共享,里面的数据所有动态资源都可以写入和获取

     服务器启动的时候创建,服务器关闭的时候销毁,因为这是全局应用程序对象,全局共享对象。

1.2.2. 可以读取全局配置参数

1.2.2.1. servletContext读取全局参数核心方法

     getServletContext().getInitParameter(name);//根据指定的参数名获取参数值

getServletContext().getInitParameterNames();//获取所有参数名称列表

1.2.2.2. 实现步骤:

  1.  在web.xml中配置全局参数
    
<!-- 全局配置参数,因为不属于任何一个servlet,但是所有的servlet都可以通过servletContext读取这个数据 -->
  <context-param>
         <param-name>param1</param-name>
         <param-value>value1</param-value>
  </context-param>
   <context-param>
         <param-name>param2</param-name>
         <param-value>value2</param-value>
  </context-param>
 
————————————————

原文链接:https://blog.csdn.net/qq_36371449/article/details/80314024
  1.  在动态资源servlet里面使用servletcontext读取全局参数代码
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
          
           //使用servletContext读取全局配置参数数据
           //核心方法
           /*getServletContext().getInitParameter(name);//根据指定的参数名获取参数值
           getServletContext().getInitParameterNames();//获取所有参数名称列表*/
          
           //打印所有参数
           //1.先获取所有全局配置参数名称
           Enumeration<String> enumeration =  getServletContext().getInitParameterNames();
           //2.遍历迭代器
           while(enumeration.hasMoreElements()){
                    //获取每个元素的参数名字
                    String parameName = enumeration.nextElement();
                    //根据参数名字获取参数值
                    String parameValue = getServletContext().getInitParameter(parameName);
                    //打印
                    System.out.println(parameName+"="+parameValue);
           }
         }
————————————————

原文链接:https://blog.csdn.net/qq_36371449/article/details/80314024

1.2.3. 可以搜索当前工程目录下面的资源文件

1.2.3.1. 核心方法

     getServletContext().getRealPath(path)//,根据相对路径获取服务器上资源的绝对路径

     getServletContext().getResourceAsStream(path)//,根据相对路径获取服务器上资源的输入字节流

1.2.4. 可以获取当前工程名字

1.2.4.1. 核心方法

     getServletContext().getContextPath()//作用:获取当前工程名字

1.2.4.2. 代码

publicvoid doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
       
        //获取工程名字,getServletContext().getContextPath()
        response.getOutputStream().write(("工程名字:"+getServletContext().getContextPath()).getBytes());
 
    }


原文链接:https://blog.csdn.net/qq_36371449/article/details/80314024

6.6、HttpServletResponse

参考博客:https://www.cnblogs.com/xdp-gacl/p/3789624.html

参考博客:https://www.jianshu.com/p/8bc6b82403c5

web服务器接收到客户端的http请求,会针对这个请求分别创建一个代表请求的HttpServletRequest对象,和一个代表响应的HttpServletResponse对象;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

1、简单分类

负责向浏览器发送数据的方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFy4czVk-1579000970415)(data:image/png;base64,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)]

负责向浏览器发送响应头的方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kkmK1Q2v-1579000970416)(data:image/png;base64,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)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KoMfaJmb-1579000970417)(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAApwAAACJCAIAAAAOrX/zAAATAklEQVR4nO2dwXHruBJFEZdymDQUzSy0mABeFFpMDJOBEvhLZcC/sK2iCXTjAiQICDqnXK9IsNl9AYK4Iv1sh6UHz+fzz58/XUoDAADMSngCAADAFIQ/PXg+n13qAgAATEzo8n7gyet3AACAo8HUAQAAJgFTBwAAmARMHQAAYBIwdQAAgEloYeqP2+Vye6xb7tfwqwVTBwAAOJyTntQftyumDgAA0BRMfR5C6PPNFIAimKgA7Si+u+7XEMLl9njcLiFcbo/lcbuE8NW2Pv4d/nP0lNfv4frf+qtd/r///d9RhY5Sm1woW6+e4YemVTa1qsvN5CVnjvy64oHZjkoFAGsqbq3vp+7H7XZflsftcr2vm39tLffr19EWT+pJL3w16k5Z5Knr4KM+OrQz9XM4ofS6hLX9gZzc/Ww5Xc+HXziAdlTdWvfr9f5t18OauhUg5lGCxzH1vkvkyaZ+cumReV9TLw0GAJG6+2r9/9tTr99DCOHHzS8/LwpXL+CTpm69PI8bN5FxcLxdmicZX5pfb8/m+dr9659HOlW0PiZfz24a17vOoSzZ6psqychSwwi/2bRvaolhuiTldF9nUlUpp428NYB7urmn4wBgMcrPqVtmmTXRTeZz8lifD9ptr0svEdb6uFmF42290SFexJM54/zJin4hp5YTZuncI8k/PW5c/2tFlnLCyBfNEN+5lWsHADsZxdQXw7TEh/JkY8XDd7ZuqdlbdSvyfD2pLykUU3+1JFf5OFh8jLOqK4VKTT2r2c8mWqAoSR86y9TX+LUUDZak07qZzOZ0E1MHaMFApv6F4rjOIeWJvPTDgZJf0VnxdL7Js9PUnYVeibRwns+UZ7vSxb2pqeuSsk+rWVPPlijSkJURbx/bzVhPskU5BADVjGLqh782d4L3PPH32l5cU18Ee/O3lbX7kCdgq3F91PeGpqauO01pNx1TVwY5q6FCUmkJ5YOCcnqRAAAoYixTF99dx4eySeKjsa+L78yD8XPqin5HrZ/H79qi2Zv1LjS5Fm8iLa+1EiZZH92Ebc51CiUP+ZFWd0RJMdbpVt9fg5yM9PvuC7B66usUu+nU8gU4Y/VqVLoJAKWMYuqwn3ihHHzp3JhBRyUvuks6p2jfbg5yrQGmBFOfEP0hrDsDSu0l6eSiA448AOxnCFOPX0TzpXx1uXYAADAsQ5g6AAAA7AdTBwAAmARMHQAAYBIwdQAAgEnA1Lth/aQvtKbRgHf57+vHRp6TZ4QqE1A6UCMPLMvggWDqfeB3cfSl0YCPaerLccIw9aEoHajBB3Zwee8Cpt6HOlNn0h/FBKbucNSvIXq7X2f0aTQy9V5Xmdl1CJh6H45aZKEOTP3MPNAITB1iMPVuWDM4+Y125xvwpd+b14PXYb4kX0+84etxijr9LR0EJb/Sbh2y+uWUTqZNqlWUbMSIRavzOOOjl/Az+7tBmz+WEr1fIcUh4yDq319CacyOQ7acv5vsV5zH39UH4XPA1HuSvHP0XSVgZ/xGZLyhtydjlPg9dZVO7cxflGexhyIpUk/rt1v99dHz7JmH2Vnt5C+dP46euvmw2TjqfnT0l17HiutVNP4xfvxRdf0TPxlMvT/xir+5Q5KRVotYMZk/Ky+r00pYsSgr7Vk9YqecRcqqUp1Hv2RxFXEt0xdHUUA2z57xF2d1chDEeVg9H+IqlpjwY2ZF45DNb5Vr1C8rbUW/LM2lda2cFeP8IWDqQ+DcAMmwTWPpCuInFIs68bGe0kXKuduV/FnEuo6GQ/IoIuN/s6n0xVERoOSpWFWdSes3Kte9tL/+fHM0bDbqxsHJL7Yrya1aSto9/RI1KHX3zLfPAVPvQ91kLb2H9bqlOUtd4UBTV+J1YWKenfqdVFmRU5p6xTzfMwLV90W2faepN7ovqvNbaatNvagQpn4ImHofGt1svUy9aDFSPqqPttgpTxshhIqnE12nvtR2N3VxXr3I1m2tp5GptzDd5HxTSojzMym79fxR4hX94pjMDabeh/Ab65B1opJHLO2c5YclD1mnFOVxdqvHLRnp7zr5k71bonXHyZwV+TrF2vZTieOpCBDzFHUtHlulX05P9/RX71csb71RMQ7Z/En9cXWlxGLPzziP1aL3axGu10aYo8TX78j+QDB1OAPuNFgTL9y9lABMBqYOzSn9gA+fQMWTHwBkwdQBAAAmAVMHAACYBEwdAABgEjB1AACAScDUAQAAJiE8AQAAYArCnx48n88udQEAACaG1+8AAACTgKkDAABMAqYOAAAwCZg6AADAJGDqAAAAk9DC1B+3y+X2WLfcr+FXC6YOAABwOCc9qT9uV0wdAACgKZj6efAnJgHeEe5ceCOKJ+v9GkK43B6P2yWEy+2xPG6XEL7a1se/w3+OnvL6PVz/+/r6+9//vbbD9b9Dcu7VlloXWi8WZ/696v1/HnvKpZNLvMlwrCS97s5RmnJywpRUzNTvp+7H7XZflsftcr2vm39tLffr19EWT+pJr103HmLGR+XpuCicUHpdwtqGdnCJFTB1+ASqZur9er1/2zWmLmXouiKcvOKfXBoWLrHGTqlv1FP4ZOqm6fr/t6dev4cQwo+bX37efK1ewCdNff3CfG2iceMmMg6Ot5N59PZsnq/dv/55pFNFy0HyfeCmcb3rHMqSrb6pkozM1nJO3DzYxbXEMF2ScrqvM6mqCCXnetc5pNTyq+8cz2QVa+iStcQwXVLF0CWrxwKU0wGGZZSfU7fMOGvSm8yW37feXpeO+2stB5ulJN7WGx3iFTOZM86frOgXcmo5YZbOPZL80+PG9b9WZAVcYl/nzkscbztDJ46SeDrAmIxi6othiuJDebJRfLjfHK3O8/WknuyvYuqvluRKFwdbzxNidaVQ6Yqf1exnK1pz61b8127c99jU1/i1RBlOdUVnURWx0Idc4qLq1nXH1OEtGMjUv1Cc2zkkPlUnT6l4Ot/k2WnqzvqrRFokfSVb8bVdupY1XfF1Sc7pyY3Y1LMlFLjETvt+SUVDV/SRIiseYExGMfVjX7+fv724pr4Ia5+/rVjUIY9HVuP6qGMhzrbfWKHTp7Sbjqkrg1wkI7nNJfbPdRKK2qpHqVQVQEfGMnXx3Xh8aLOb/Dl1Jb/ypt35XoClc9HWvvAb59w40lqIrYRJ1kc3YZtznULJQ36k1R1RUox1utX31yAnI/2++wQusdsdUZKDMibiKG0a/SoAYzKKqX8CydWnixKR4LpOF7pLKi06yLhZdB/PmMElAQwOpt6BogeRvgwotZekoqIDjpvFgFIHlATwLgxh6vGL7jm+uowtAAB8LEOYOgAAAOwHUwcAAJgETB0AAGASMHUAAIBJwNS7Yf3sLLSm0YCffB31ckcJO6eD3A4iLQaK5WgCMPU+8Kst+tJowMc09eU4YZj6UEwwjeFwMPU+1Jk6N9tRzL0aHvVrjo7KA42YexpDHZh6H45aZKGOuVdDTP1DmHsaQx2YejesOyf5jXbnG/Cl35vXg9dhviRfT7zh63GKOv0tHQQlv9JuHbL65ZROpk2qVZRsxIhFq/M446OX8DP7u0GbP5YSvV8hxSHjIOoXS5SO2/rEOI+/q/cXWoOp9yS5gui7SsDO+I3IeENvT8Yo8XvqKp3amb8oz2IPRVKkntZvt/rro+fZMw+zs9rJXzp/HD1182GzcdT96Ogv7ZevX9mtzgNdwNT7Y33szVp+skWsmMyflZfVKdpMtYk6+Z1xK9Ljj7/fXyWPfsniKuIaqi/KooBsnj3jL87q5CCI87B6PsRVLDHhx9SLxiGb3yon9ss5N1nXibRyVvQXmoKpD4Fz4yXDNo2lK4ifUCzqxMd6ShcpZ5VR8mcR6zoaDsmjiIz/zabSF2VFgJKnYjV3Jq3fqFz30v76883RsNmoGwcnv9iu5Bf7mEx74HWH1mDqfai7SUrXJr1uac5SVzjQ1JV4XZiYZ6d+J1VW5JSmXjHP94xA9X2Rbd9p6o3uizjGPxFTnwlMvQ91N+3+xbqRqRctRsojQuvF7sD865iKpyJdZ/bq65GtTV2cVy+ydVvraWTqh9fdxBx+HZV4ZZ7r2uBwMPU+hN9Yh6wTlTxiaecsPyx5yDqlKI+zWz1uyUh/18mf7N0SrXdO5qzI1ynWtp9KHE9FgJinqGvx2Cr9cnq6p796v2J5642KccjmT+qPq2dLKHXjRmuUrPGJFcL5YOpwBtzhsCY2jF5KACYDU4fmFD24wIdQ+kQLAAqYOgAAwCRg6gAAAJOAqQMAAEwCpg4AADAJmDoAAMAkhCcAAABMQfjTg+fz2aUuAADAxPD6HQAAYBIwdQAAgEnA1AEAACYBUwcAAJgETB0AAGASWpj643a53B7rlvs1/GrB1AEAAA7npCf1x+2KqQMAADQFU38/+FOV8BYwUQHOp/iuu19DCJfb43G7hHC5PZbH7RLCV9v6+Hf4z9GzXr+H63+brz1J/v73fztTxTn3JFmMhbL16nnm373e/2e25/OSXj3af93nuxYAg1Nxy30/dT9ut/uyPG6X633d/GtruV+/jrZ4Unc8ssg+k8HrxkPM+Kg8HVfJE0qvS1jbYNFolDB1gDei6pa7X6/3b7vG1HUOeNzvukSebOonl56AAU19/+kAUETd/bb+/+2p1+8hhPDj5pefV3irF/BJU7dem8eN2XfsyQx//fPQ8zimbtVV2rN5LKnfR6P1MfmCdNO43nUOZclW31RJRmZrOSdunt3jWmKYLkk53deZVKVT2vFsoXWM1YX4lLj6Eo2JcjoAtGaUn1O3TDRrrsn8jrOKeSy/b729kbpVJTzIJrf1RofYq5I54/zJin4hp5YTZuncI8k/PW5c/2tFlqL0SM9fOhnE6y6eDgBNGcXUF8PMxIfpZKpNy1//PJJHi16/+y8JSj8EWP16Sd2qkt9Oxw9hVrDyeOdUVwqVmnpWs5+tyIQUU3cyx32PTX2NX0vR4EjaY+obtaXVnW5i6gBnMpCpf7HHuZ1Dx5q6X7Ti6dySuj1UaGPx+qtEWiQ/OmQrvrZLF/empq5Lyjpo1tSzJYo0KJLEhOJkKPqQZNUCgHMYxdRPeP1+uKm3e/1umfoi2Ju/rVjUIU/AVuP6qPMpwdn2Gyt0+pR20zF1ZZCzGqyccVg2oZin+roXSQKAQxjL1MV32vEhK8/60TnetfK8dpM/p67oVN60W+/enf4umr1Z70KTJrqJtLzWSphkfXQTtjnXKZQ85Eda3RElxVinW31/DXIy0u+7LyDbo4rMeq1klaSSEE1FRQwAHMUopg46yeW4ixKRjR90VPKiu6RBxqEpn9BHgNHA1N+Y5LPRmAwotZek0cYBAGZiCFOPX1Dz5b+EBwAAiBnC1AEAAGA/mDoAAMAkYOoAAACTgKkDAABMAqbeDeuHgKE1jQb85OtY9CPphwg7p4PcDiLiQH3UeLKcLph6L/gdHX1pNOBjmvpynDBMfSgw9SSf1t8NmHof6kz9wyfrgUxg6g5H/Xqit/s1R5/G3NO4mnfXvxNMvQ9HLbJQx9yrIab+Icw9jat5d/07wdS7Yc285DfanW/Al35vXg9eh/mSfD3xhq/HKer0t3QQlPxKu3XI6pdTOpk2qVZRshEjFq3O44yPXsLP7O8Gbf5YSvR+hRSHjIOoXy/h9Ch51OqUU1Qfh/Wuot853R8Eq7/OrjKY7wKm3pPkHaLvKgE74zci4w29PRmjxO+pq3RqZ/6iPIs9FEmRelq/3eqvj55nzzzMzmonf+n8cfTUzYfNxlH3o6O/6XV04i2dirC6+S/WPUq/ouctwNT7E8/4NVak1SJWTObPysvqFG1GXzT99qwesVObxdQZf7+/Sh79ksVVxDVIX9REAdk8e8ZfnNXJQRDnYfV8iKtYYsKPqReNQza/VU7slxWW7a+j0NKpXBddcxzvq8rqt3JWXK/BwdSHwJm4ybBNY+kK4icUizrx2Tt5z+J17Erh13U0HJJHERn/m01VuojrUiv66yS3Jq3fqFz30v76883RsNmoGwcnv9iul1DyZOM3hxRbVQ758eI1SpY4cN6OD6beh7pJVro26XVLc5auJgeauhKvCxPz7NTvpMqKnNLUK+b5nhGovi+y7TtNvdF94VfJ5tFNvbTdP+TEFwnG1DuAqdfdtPsX60amXrQYKR+xWy92B+Zfx1Q8Veg69yy1J5u6OK9eZOu21tPI1A+vu4npZeobPfF1PGr+V+jJxiv3qT62A4Kp9yH8xjpknajkEUs7Z/lh1s2cbc/mcXarxy0Z6e86+ZO9W6L1wsmcFfk6xdr2U4njqQgQ8xR1LR5bpV9OT/f0V+9XLG+9UTEO2fxJ/XF1Mbk+PlZLrGQT48QnxSgkg5PD5ZSIw/x+FSkcCkwdzuB97xBogWMG8EZwHQcEU4fmVHw2h+mpe2iD0eA6jgamDgAAMAmYOgAAwCRg6gAAAJOAqQMAAEwCpg4AADAJ4QkAAABTEP704Pl8dqkLAAAwMbx+BwAAmARMHQAAYBL+D/gMwAuoYqFtAAAAAElFTkSuQmCC)]

负责向浏览器发送响应状态码的方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zK57b8IS-1579000970417)(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAb4AAAAxCAIAAAAqflsHAAAET0lEQVR4nO2c0XWrMAxAPVcGYh5GyBSZ4m3AEmxAP5qeR4wlS8aAaO89/UiMkIXBtzg0TUsY5nl+Pp9XVwEAUCfNAADgJD3DMM/z1SUAAJhIV9/2/mdmwQ4ANwF1AgC4QZ0AAG5QJwCAG9QJAODmNHVO4+MxTuuW15A+WlAnANyFK+86p3FAnQBwR1DnxaQU4jOTIGUA3IU+E+Y1pJQe4zSNj5Qe47RM4yOl77b19nf4z9YTF+xp+Lf+OagXL1thXagw7Algp9dsed9BTuP4WpZpfAyvdfPHq+U1fG894q6zaMZ1YxbgNWlf8zbb6gjNoU4AO/1my2sYXm8pRlanfVOXeC3VDlUdpDnsCWCk41RZP0MvLdhTSunHme8F+8eSvahOaaG9bcwiM8FJLXq8Jf/6rV5n3sWnp35GJGUt6xfrsCxYohgsZUCdAEYCTZWtOqWFdtsC3KjUhvwNdS6Cp4o+3W4yOq64i5IHdQIYCTRV9LvOYqN0l6f00qDaZnVK9b832dRZfa3jurVEnQBGAk0V5bNOr++UXoypsjW4Hq/fXYqNp6jTtS/qBDASaKoct2C/Kr6u1NofJ+1Up2vBjjcB7ASaLZI6q2v2LI/rWU0xfrtLdQ1ejNf7XTbmyp7eZE9ypIdICsrjIJ4RAewh0Gzh20QXEqQMgLsQaML8TXUCwB2Jq87tEvh3/Fw4wgDQi7jqBAAIC+oEAHCDOgEA3KBOAAA3qDMW3v/ucXQlFxZwL7oM15mnXu+Fs18l0Oigzmh/o355Afdi53Cd/80u1LmHQKODOtvU2esSr34r9CD2fB8/FB3VeQRXnd/fSqCxQ51tlzLqDALq/FMEGjvUuchXc/FTMOWDUddnplJwKn2VXqnH24WxfkuSLKZtHLJdjMdbLdXeoyXP+q2xCyV5MYmS1j6eep1Skm3+7Qspft0iHYUyFJaD+khljDsB1PlN8Xzb31oCpH71StZXpyt/3/rt8Q3j4D3eLuMjhen9St258kvH4q1H6XRbp/d8SQdrid/Trw7qDIr0K7Eq1mKLt8diS3Zp2n9R6wHS1ubj9TrFUoklf/P4SL0blW3Eq8Iu11VxF2l8Oo6/pb1ajw7qjItRAdWr09ud1NKsJL0eqf5qGZYA1zgcNHWNxFfn4r+uqifXkr+XOo35jaDOQLRNxeqJb77K+6qhmtYY4I2vtnt3/MvqdAVIMd4LsqM6LfFGUGcg2i6FZpXoezXXU818qDrXNxQN41DUk0VhO/sthkVT587xrOaxtB9xN6q0K8eIOgORPpE2STta8lgKyJLob43zx1X/dpfi1mL8emvbOHjHf9uvHq/0aOm37aCyUreHuR3AbReurvVgV35Xnobj0usRD1A//jNBnQCwparpSwhUE+oEgAzjTe75BCoIdQLAXUCdAABuUCcAgBvUCQDgBnUCALhJMwAAOEnPMMzzfHUJAAAmWLADALhBnQAAbr4AWdWpW2F4mXgAAAAASUVORK5CYII=)]

2、常见应用

  1. 向浏览器输出消息
  2. 下载文件
    1. 要获取下载文件路径
    2. 下载的文件名是啥
    3. 设置想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutPutStream对象
    7. 将FileOutPutStream流写入到buffer缓冲区
    8. 使用OutPutStream将缓冲区中的数据输出到客户端
1 package gacl.response.study;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.io.PrintWriter;
 9 import java.net.URLEncoder;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15  * @author gacl
16  * 文件下载
17  */
18 public class ResponseDemo02 extends HttpServlet {
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         downloadFileByOutputStream(response);//下载文件,通过OutputStream流
23     }
24 
25     /**
26      * 下载文件,通过OutputStream流
27      * @param response
28      * @throws FileNotFoundException
29      * @throws IOException
30      */
31     private void downloadFileByOutputStream(HttpServletResponse response)
32             throws FileNotFoundException, IOException {
33         //1.获取要下载的文件的绝对路径
34         String realPath = this.getServletContext().getRealPath("/download/1.JPG");
35         //2.获取要下载的文件名
36         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
37         //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
38         response.setHeader("content-disposition", "attachment;filename="+fileName);
39         //4.获取要下载的文件输入流
40         InputStream in = new FileInputStream(realPath);
41         int len = 0;
42         //5.创建数据缓冲区
43         byte[] buffer = new byte[1024];
44         //6.通过response对象获取OutputStream流
45         OutputStream out = response.getOutputStream();
46         //7.将FileInputStream流写入到buffer缓冲区
47         while ((len = in.read(buffer)) > 0) {
48         //8.使用OutputStream将缓冲区的数据输出到客户端浏览器
49             out.write(buffer,0,len);
50         }
51         in.close();
52     }
53 
54     public void doPost(HttpServletRequest request, HttpServletResponse response)
55             throws ServletException, IOException {
56         doGet(request, response);
57     }
58 }

下载中文文件时,需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, “字符编码”)),否则会出现文件名乱码。

1 package gacl.response.study;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.io.PrintWriter;
 9 import java.net.URLEncoder;
10 import javax.servlet.ServletException;
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 /**
15  * @author gacl
16  * 文件下载
17  */
18 public class ResponseDemo02 extends HttpServlet {
19 
20     public void doGet(HttpServletRequest request, HttpServletResponse response)
21             throws ServletException, IOException {
22         downloadChineseFileByOutputStream(response);//下载中文文件
23     }
24 
25     /**
26      * 下载中文文件,中文文件下载时,文件名要经过URL编码,否则会出现文件名乱码
27      * @param response
28      * @throws FileNotFoundException
29      * @throws IOException
30      */
31     private void downloadChineseFileByOutputStream(HttpServletResponse response)
32             throws FileNotFoundException, IOException {
33         String realPath = this.getServletContext().getRealPath("/download/张家界国家森林公园.JPG");//获取要下载的文件的绝对路径
34         String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);//获取要下载的文件名
35         //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
36         response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
37         InputStream in = new FileInputStream(realPath);//获取文件输入流
38         int len = 0;
39         byte[] buffer = new byte[1024];
40         OutputStream out = response.getOutputStream();
41         while ((len = in.read(buffer)) > 0) {
42             out.write(buffer,0,len);//将缓冲区的数据输出到客户端浏览器
43         }
44         in.close();
45     }
46     
47     public void doPost(HttpServletRequest request, HttpServletResponse response)
48             throws ServletException, IOException {
49         doGet(request, response);
50     }
51 }

文件下载注意事项:编写文件下载功能时推荐使用OutputStream流,避免使用PrintWriter流,因为OutputStream流是字节流,可以处理任意类型的数据,而PrintWriter流是字符流,只能处理字符数据,如果用字符流处理字节数据,会导致数据丢失。

3、验证码功能

验证怎么来的?

  • 前端实现
  • 后端实现,需要用到java的图片类,生成一个图片

这个可以当做一个工具类来使用,不必自己写出来,要用的时候复制,然后可以局部的改改代码,就可以变成另外的验证码了。

public class ResponseDemo4 extends HttpServlet {

    public static final int WIDTH = 120; // 生成的图片的宽度
    public static final int HEIGHT = 35; // 生成的图片的高度

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 在内存中创建一张图片
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 得到图片
        Graphics g = image.getGraphics();

        // 1.设置图片的背景色
        setBackGround(g);

        // 2.设置图片的边框
        setBorder(g);

        // 3.在图片上画干扰线
        drawRandomLine(g);

        // 4.在图片上写随机数
        String random = drawRandomNum((Graphics2D) g);
        request.getSession().setAttribute("checkcode", random); // 将随机数存在session中

        /*
         * 5.图形写给浏览器
         */
        response.setContentType("image/jpeg")
        // 发响应头控制浏览器不要缓存图片
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        ImageIO.write(image, "jpg", response.getOutputStream());

    }

    /*
     * 设置图片的背景色
     */
    private void setBackGround(Graphics g) {
        // 设置颜色
        g.setColor(Color.WHITE);
        // 填充区域
        g.fillRect(0, 0, WIDTH, HEIGHT);
    }

    /*
     * 设置图片的边框
     */
    private void setBorder(Graphics g) {
        // 设置边框颜色
        g.setColor(Color.BLUE);
        // 边框区域
        g.drawRect(1, 1, WIDTH-2, HEIGHT-2);
    }

    /*
     * 在图片上画干扰线
     */
    private void drawRandomLine(Graphics g) {
        // 设置颜色
        g.setColor(Color.GREEN);
        // 设置线条个数并画线
        for(int i=0;i<5;i++) {
            // 生成干扰线随机的起始坐标
            int x1 = new Random().nextInt(WIDTH); // 生成0~WIDTH(不包括WIDTH)的随机数
            int y1 = new Random().nextInt(HEIGHT);

            // 生成干扰线随机的结束坐标
            int x2 = new Random().nextInt(WIDTH);
            int y2 = new Random().nextInt(HEIGHT);

            g.drawLine(x1, y1, x2, y2);
        }
    }

    /*
     * 在图片上写随机数
     */
    private String drawRandomNum(Graphics2D g) {
        // 设置颜色
        g.setColor(Color.RED);
        // 设置字体
        g.setFont(new Font("宋体", Font.BOLD, 20));
        // 常用的中国汉字(汉字区间:[\u4e00-\u9fa5])
        String base = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6";

        StringBuffer sb = new StringBuffer();
        int x = 5;
        // 控制字数
        for(int i=0;i<4;i++) {

            int degree = new Random().nextInt()%30; //生成-30-30范围的随机数

            String ch = base.charAt(new Random().nextInt(base.length()))+"";
            sb.append(ch);
            // 写入字之前,设置好旋转
            g.rotate(degree*Math.PI/180, x, 20); // 设置字体旋转角度
            g.drawString(ch, x, 20);
            // 这次旋转不能影响下一次的旋转,所以要将上一次的旋转清掉,转回去
            g.rotate(-degree*Math.PI/180, x, 20);
            x+=30;
        }
        return sb.toString();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
4,设置响应头控制浏览器的行为

1,定时刷新页面

response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次

2,禁止缓存当前文档内容

response.setDateHeader("expries", -1);

response.setHeader("Cache-Control", "no-cache");

response.setHeader("Pragma", "no-cache");

6.7、HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过HttpServletRequest的方法,获得客户端的所有信息。

1、获取前端传递的参数、请求转发

参考博客:https://www.iteye.com/blog/sihailoveyan-2430052

面试题:请你聊聊重定向和转发的区别?

相同点:

  • 页面都会实现跳转

不同点:

  • 请求转发的时候,url不会产生变化:307
  • 重定向的时候,url地址栏会发生变化:302

7、Cookie、Session

7.1、会话

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

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

7.2、保存会话的两种技术

Cookie

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

Session

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

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

7.3、Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName()//获得cookie的key
cookie.getValue()//获得cookie中的值
new Cookie("lastLoginTime",System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie1);//响应给客户端一个cookie

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

一个网站cookie是否存在上限!聊聊细节问题

  • 一个cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie;
  • 300个cookie浏览器上限;
  • cookie大小有限制4kb;

删除cookie:

  • 不设置有效期,关闭浏览器,自动失效;
  • 设置有限期时间为0;

7.4、Session(重点)

什么是Session:

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

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
  • Session是把用户的数据写到用户独占Session中,服务端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建;

使用场景:

  • 保存一个用户登录信息;
  • 购物车信息;
  • 在整个网站中,经常会使用的数据我们将它保存在session中

登录页面代码实现:

SessionId: <%= session.getId() %>
    <br/><br/>
    
    isCreateNew:<%= session.isNew() %>
    <br/><br/>
    
    maxInActiveInterval:<%= session.getMaxInactiveInterval() %>
    <br/><br/>
    
    CreatedTime:<%= session.getCreationTime() %>
    <br/><br/>
    
    lastAccessedTime: <%= session.getLastAccessedTime() %>
    <br/><br/>
    
    <%
        Object username = session.getAttribute("username");
        if(username == null){
            username = "";
        }
    %>
    <form action="<%= response.encodeURL("loginSuccess.jsp") %>" method="post">
        username: <input type="text" name="username" value="<%= username%>"/><br/>
        <input type="submit" value="登录"/>
    </form>

登录成功页面:

SessionId: <%= session.getId() %>
    <br/><br/>
    
    isCreateNew:<%= session.isNew() %>
    <br/><br/>
    
    maxInActiveInterval:<%= session.getMaxInactiveInterval() %>
    <br/><br/>
    
    CreatedTime:<%= session.getCreationTime() %>
    <br/><br/>
    
    lastAccessedTime: <%= session.getLastAccessedTime() %>
    <br/><br/>
    
    Hello: <%= request.getParameter("username") %>
    <br/><br/>
    
    <%
        //将username存储于session之中,便于在整个会话过程中记住当前user;
        // 当然服务器端可以找到session还是通过cookie(URL重写)在客户端和服务器端传递JSESSIONID
        session.setAttribute("username", request.getParameter("username"));
    %>
    

        <!-- 
        
            cookie被禁用的情况下使用url重写的方式传递JSSESSIONID;
            重写使用:response.encodeURL或response.encodeRedirectURL()都行
        -->
        

    <a href="<%= response.encodeURL("login.jsp") %>">重新登录</a>
    <a href="<%= response.encodeURL("loginOut.jsp") %>">注销</a>
    

注销:

SessionId: <%= session.getId() %>
    <br/><br/>
    
    isCreateNew:<%= session.isNew() %>
    <br/><br/>
    
    maxInActiveInterval:<%= session.getMaxInactiveInterval() %>
    <br/><br/>
    
    CreatedTime:<%= session.getCreationTime() %>
    <br/><br/>
    
    lastAccessedTime: <%= session.getLastAccessedTime() %>
    <br/><br/>
    
    ByeBye: <%= session.getAttribute("username") %>
    <br/><br/>
    
    <%
        //注销session
        session.invalidate();
    %>
    
    <a href="login.jsp">重新登录</a>
    

8、JSP

8.1、什么是JSP

Java Server Pages :Java服务器端页面,也和Servlet一样,用于动态Web技术;

最大的特点:

  • 写JSP就像在写HTML
  • 区别:
    • HTML只给用户提供静态数据
    • JSP中可以嵌入Java代码,为用户提供动态数据;

8.2、JSP原理

思路:JSP到底是怎么执行的?

  • 代码层面没有任何问题
  • 服务器内部工作
    • Tomcat中有一个work目录
    • IDEA中使用Tomcat的会在IDEA的Tomcat中产生一个work目录

点进去发现jsp页面转变成了Java程序;

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet;

JSP最终也会转换成为JAVA类!

JSP本质上是个Servlet

运行原理:

当第一次访问jsp页面时,会向一个servlet容器(tomcat等)发出请求,servlet容器先要把 jsp页面转化为servlet代码(.java),再编译成.class 文件 再进行调用。当再次访问jsp页面时 跳过翻译和编译的过程 直接调用

执行过程:

1、 客户端发出请求

      2、web容器将jsp转化为servlet代码(.java)

      3、web容器将转化为servlet代码编译(.class)

      4、web容器加载编译后的代码并执行

      5、将执行结果响应给客户端

img

在jsp中:

只要是Java代码就会原封不动的输出;

如果树Html代码,就会被转换为:

out.write("<html>\r\n");

这样的格式输出出来;

8.3、JSP基础语法

任何语言都有自己的语法,java中有,那jsp作为java技术的一种应用,它拥有一些自己扩充的语法(了解即可),java所有语法都支持!

JSP表达式:

<%--  JSP表达式
       作用:用来将程序的输出到客户端
       <%= 变量或者表达式%>--%>
<%= new java.util.Date()%>

jsp脚本片段:

<%--  jsp脚本片段--%>
<%
  int sum = 0;
  for (int i = 0; i <= 100; i++) {
    sum+=i;

  }
  out.println("<h1>"+"Sum="+sum+"<h1>");
%>

脚本片段的再实现:

<%
  int x = 10;
  out.println(x);
%>
<p>这是一个jsp文档</p>

<%
  int y = 20;
  out.println(y);
%>
<hr>

<%-- 在代码中嵌入html元素 --%>

<%
  for (int i = 0; i < 5; i++) {

%>
<h1>Hello,World<%=i%></h1>
<%
  }
%>

JSP声明:

<%!
    static {
      System.out.println("Loading Servlet!");
    }

    private int globalVar = 0;

    public  void yuan(){
      System.out.println("进入了方法yuan!");
    }
%>

JSP声明:会被编译到jsp生成的java的类中!其他的,就会被生成到_jspService方法中!

在jsp中嵌入java代码中即可!

<% %>
<%=  %>
<%!  %>
<%----%>

jsp的注释,不会在客户端显示,html的注释会被显示;

8.4、JSP指令

<%@ page … %>定义网页依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %>包含其他文件
<%@ taglib … %>引入标签库的定义

参考博客:https://www.runoob.com/jsp/jsp-directives.html

8.5、9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application 【ServletContext】 存东西
  • config 【ServletConfig】
  • out
  • page,不用了解
  • exception
<%


    pageContext.setAttribute("name1","智能1号");//保存的数据只在一个页面中有效
    request.setAttribute("name2","智能2号");//保存的数据只在一次请求中有效,请求转发会携带这个参数
    session.setAttribute("name3","智能3号");//保存的数据只在一次回话中有效,从打开浏览器到关闭浏览器
    application.setAttribute("name4","智能4号");//保存的数据只在服务器中有效,从打开服务器到关闭服务器


%>

Request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完就没用了;

Session:客户端向服务器发送请求,产生的数据,用户用完一会儿还有用,比如:购物车;

Application:客户端向服务器发送请求,产生的数据,一个用户用完其他用户还可能使用,比如:聊天数据;

8.6、JSP标签、JSTL标签、EL表达式

要导入的配置:

 <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/taglibs/standard -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

EL表达式:${}

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
  • 调用java方法(不用)

JSP标签:

<%--http://localhost:8080/jsptag.jsp?name=yuan&age=12--%>
<h1>1</h1>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="yuan"/>
    <jsp:param name="age" value="12"/>
</jsp:forward>

JSTL表达式:

参考博客:https://www.runoob.com/jsp/jsp-jstl.html

JSTL标签库的使用就是为了弥补HTML标签的不足,他自定义了许多标签,可以供我们使用,标签的功能和java代码一样!

核心标签(掌握部分):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bTJFiZiQ-1579000970418)(/Users/mac/Library/Application Support/typora-user-images/image-20191227140120234.png)]

JSTL标签使用步骤:

  • 引入对应的taglib
  • 使用其中的方法
  • 在tomcat中也需要引入jstl的包,否则会报错:JSTL解析错误

9、JavaBean

实体类

JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库的字段做映射 ORM

ORM:对象关系映射

  • 数据库的表---->Java的类
  • 字段---->属性
  • 行记录---->对象

10、MVC三层架构

10.1、三层架构

参考博客:https://www.jianshu.com/p/731d027b2d91

什么是MVC:Model View Controller 模型、视图、控制器

约定:

  • Servlet和JSP都可以写Java代码:为了易于维护和使用

  • Servlet专注于处理请求,以及控制视图跳转

  • JSP专注于显示数据

控制器:Controller Servlet :

  • 接受用户的请求
  • 响应给客户端内容(交给业务层去做)
  • 重定向或者转发(视图跳转)

View:视图层:JSP

  • 展示数据模型
  • 提供用户操作

数据库:

  • 增删改查

JavaBean

  • pojo
  • entity…

Service:

  • login登录
  • logout注销
  • 查询全部用户

img

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD(Dao)

View:

  • 展示数据
  • 提供链接发起Servlet请求(a,form,img…)

Controller:

  • 接收用户的请求:(req:请求参数、session信息…)
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登录--->接收用户的登录请求---->处理用户的请求(获取用户登录的参数;username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)---->Dao层查询用户名和密码是否正确---->数据库

10.2、早些年架构

用户直接访问控制层,控制层就可以直接访问数据库;

servlet---->CRUB(增删改查)---->数据库
  弊端:程序十分臃肿,不利于维护    servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
  
 架构:没有什么是加一层解决不了的!如果不行,再加一层!
  程序员调用:
  JDBC
  操作:
  MySQL、Oracle、SQLServer....

11、Filter(重点)

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证

Filter开发步骤

  1. 导包
  2. 编写过滤器
    • 必须导这个Filter包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5fcci8N-1579000970419)(/Users/mac/Library/Application Support/typora-user-images/image-20191227230432833.png)]

​ 实现Filter接口,重写对应的接口即可

package com.yuan.filter;

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

public class CharacterEncodingFilter implements Filter {

    //初始化
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter已经初始化了");

    }

//    1.过滤器中的所有代码,在过滤特定请求的时候都会执行
//    2.必须要让过滤器继续执行
 //   filterChain.doFilter(servletRequest,servletResponse);
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前.....");

        filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就被拦截停止

        System.out.println("CharacterEncodingFilter执行后.....");
    }
    //web服务器关闭的时候,过滤器才会销毁
    public void destroy() {
        System.out.println("CharacterEncodingFilter已经销毁了");

    }
}

配置:

 <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.yuan.filter.CharacterEncodingFilter</filter-class>
    </filter>
<!--    只要是/Servlet的任何请求,都会经过这个过滤器-->
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/Servlet/*</url-pattern>
    </filter-mapping>

12、监听器

实现一个监听器的接口;(有N种)

  1. 编写一个监听器

    实现监听器的接口

  2. web.xml中配置监听器

  3. 看情况是否使用!

13、过滤器、监听器的常见应用

监听器:GUI编程中经常使用

统一编码,统一用户认证,屏蔽非法文字,进行响应数据压缩等。

用户登陆之后才能进入主页!用户注销后就不能进入主页了!、

  1. 用户登陆之后,向Session中放入用户的数据;
  2. 进入主页的时候要判断用户是否已经登陆;要求:在过滤器中实现;

14、JDBC

什么是JDBC:java链接数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nTWsMSv8-1579000970419)(/Users/mac/Library/Application Support/typora-user-images/截屏2020-01-12上午11.25.41.png)]

需要jar包支持:

  • java.sql
  • Javax.sql
  • Mysql-connect-java…(连接驱动必须要的)

实验环境搭建:

导入数据库依赖:

 <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

IDEA中连接数据库:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v15mL8SO-1579000970420)(/Users/mac/Library/Application Support/typora-user-images/image-20200112123822766.png)]

JDBC固定步骤:

  1. 加载驱动
  2. 连接数据库,代表数据库
  3. 向数据库发送SQL的对象Statement : CRUD
  4. 编写SQL(根据业务,不同的SQL)
  5. 执行SQL
  6. 关闭连接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d7hp488g-1579000970420)(/Users/mac/Library/Application Support/typora-user-images/image-20200112124228750.png)]

事务:

要么都成功,要么都失败!

ACID原则:保证数据的安全。

开启事务
事务提交  commit()
事务回滚  rollback()
关闭事务

转账:
A:1000
B:1000

A(900)---100--->B(1100)

Junit单元测试:

依赖:

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

简单使用:

@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!

    @Test
    public void test(){
        System.out.println("Hello World");
    }

成功提示绿色,失败提示红色!

搭建一个环境测试一波事务!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaWeb 的相关文章

  • 实现serializable序列化接口

    1 什么是序列化和反序列化 Serialization 序列化 是一种将对象以一连串的字节描述的过程 反序列化deserialization是一种将这些字节重建成一个对象的过程 2 什么情况下需要序列化 a 当你想把的内存中的对象保存到一个
  • 在Vue下如何用js代码将13位的时间戳数据转换成正常显示的时间?

    问题描述 在使用Vue时 如果页面没有渲染完成 通过js代码是拿不到页面上数据的 而我们又想通过js操作数据时 就需要通过一些特别的方法 网上有各种方法 但是大部分都解释的比较模糊 这是我的一些小总结 由于不是专门玩前端的 但是又不想用vu
  • JavaWeb案例:实现注册和登录功能

    业务需求分析 在实际开发中 通常会有专门的人去跟客户进行沟通从而了解客户需要什么样的系统 之后由专业的美工将要做的系统以图片的形式表现出来 客户确认后作出一些静态的html demo页面 然后由软件开发人员创建相关数据库 编写代码将该静态页
  • JavaWeb——JavaWeb核心之Servlet

    一 Servlet简介 1 什么是Servlet Servlet 运行在服务端的Java小程序 是sun公司提供一套规范 接口 用来处理客户端请求 响应给浏览器的动态资源 但servlet的实质就是java代码 通过java的API 动态的
  • JDBC讲解

    SUN公司于1996年提供了一套访问数据库的标准Java类库 即JDBC 一 什么是JDBC JDBC的全称是Java数据库连接 Java Database Connectivity 它是一套用于执行SQL语句的Java API 应用程序可
  • 配置Nginx以隐藏访问端口

    进入usr local nginx conf 编辑nginx conf文件 在http模块中加入下句 include vhost conf 进入usr local nginx conf vhost xxx conf 编写如下内容 nginx
  • 通俗易懂权限管理模块设计-Java

    最近一直在做CMS系统 发现一些内容其实都是重复出现的 例如权限管理模块 权限管理模块就是为了管理用户是否有权利访问某个权限 如果不能则拒绝访问 其实Java中已经有很成熟的权限管理框架 例如 Shiro Spring Security等
  • javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint

    java 验证出现如下错误 javax validation UnexpectedTypeException HV000030 No validator could be found for constraint 错误原因 Java实体类中
  • JavaWeb购物商城

    系统前台 前台用户操作 账号 test密码 test 登录页面 商品浏览 商品详情 购物车 订单页面 系统后台 后台用户操作 账号 admin密码 admin 用户登录页面 后台主页 添加商品 编辑商品 删除商品 数据库 部分代码 logi
  • ie11对象不支持此属性和方法 ie11的缓存问题

    更改eclipse的js代码 在ie11上调试 发现调用新更改的方法 在ie11的console输出里 一直提示 对象不支持此属性和方法 点击右上角设置图标 然后点击Internet选项 在常规选项卡里的 浏览器历史记录 点击设置 在弹出的
  • IntelliJ Idea 常用快捷键 列表(实战终极总结!!!!)

    自动代码 常用的有fori sout psvm Tab即可生成循环 System out main方法等boilerplate样板代码 例如要输入for User user users 只需输入user for Tab 再比如 要输入Dat
  • Get,Post请求中文乱码问题有效解决方法

    对于做Java WEB项目同学来说 中文乱码问题是一个经常遇到而又非常头痛的问题 而最容易出现乱码的环节就是在浏览器向服务器发送请求的过程 至于出现乱码的原因不是本文的关注的重点 想了解的朋友可以参考 http zhaomin819111
  • WEB-7-多线程

    多线程 一 背景 二 认识线程 Thread 1 理解 2 进程和线程的区别 高频面试题 3 使用代码创建多线程 三 线程的相关操作 1 创建线程 1 方法一 继承 Thread 类 2 方法二 实现 Runnable 接口 3 其它方法
  • Servlet接口实现类

    JavaWeb 03 Servlet 02 Servlet接口实现类 1 什么是Servlet接口 有什么用 Servlet接口来自于Servlet规范中的一个接口 这个接口存在于Http服务器所提供的jar包中 Servlet接口的具体位
  • 互联网 API 接口幂等性设计

    WEB 资源或 API 方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用 幂等性是系统的接口对外一种承诺 而不是实现 承诺只要调用接口成功 外部多次调用对系统的影响是一致的 幂等性是分布式系统设计中的一个重要概念 对超时处理 系
  • java_web:基于三层架构实现学生信息管理1.0(对学生信息的增删改查)

    学生信息管理1 0 涉及的知识点 三层架构理论 简单理解三层架构就是 上层调用下层 下层为上层提供服务 最上层 视图层 由jsp servlet组成 中间层 服务层 组装数据访问层所实现的功能 最下层 数据访问层 实现单一得某项功能 为服务
  • MVC三层架构

    1 什么是MVC Model View Controller 模型 视图 控制器 模型就是Java对应数据库的那些字段 实体类 视图 就是JSP页面 控制器 就是Servlet负责跳转页面 Controller作用 Controller其实
  • java中如何将Long类型转为Integer类型

    注意不能直接在前面加个 int 而是 将Long型转换为int型 这里的Long型是包装类型 Long a 10 int b a intValue 即long intValue
  • 【封装】实体类(entity)

    实体类entity 一 ORM 1 1 ORM 实体类 entity 零散数据的载体 1 1 1 ORM应用 一 ORM ORM Object Relational Mapping 从数据库查询到的结果集 ResultSet 在进行遍历时
  • IDEA2021从零开始搭建SSM框架手把手详细教程 (一)

    开发环境 macos IDEA 2021 mysql8 0 toma9 0 源码 https download csdn net download a2267542848 19730797 1 基本环境搭建 1 新建工程 新建后整个目录如下

随机推荐

  • 多传感器融合定位ch1

    多传感器融合定位ch1 目录 多传感器融合定位ch11 数据集下载2 数据集测试 深蓝学院多传感器融合定位课程笔记 采用的软硬件环境如下 硬件 华擎DeskMini X300W迷你主机 软件 ubuntu18 04 autolabor提供的
  • Docker网络network详解

    一 概述 Docker容器每次重启后容器ip是会发生变化的 这也意味着如果容器间使用ip地址来进行通信的话 xff0c 一旦有容器重启 xff0c 重启的容器将不再能被访问到 而Docker 网络就能够解决这个问题 Docker 网络主要有
  • ROS Ydlidar X3 激光雷达 读取数据 并计算XY坐标

    学习过程中为了防止遗忘 以此文字记录 如有错误 多多包涵 怕什么真理无穷 进一寸有一寸的欢喜 胡适 前置内容 xff1a 无 学习目标 xff1a ROS Ydlidar X3 激光雷达 读取数据 并计算XY坐标 学习内容 xff1a C
  • 个人博客项目

    一 项目功能描述 xff1a 主要分为4大功能模块 xff0c 用户登录功能 xff0c 文章评论功能 xff0c 发布和修改文章功能 xff0c 文章分类 登录首页之后可以查看所有文章的信息 xff0c 但是此时只能查看 xff0c 不能
  • 系统调用、API之间的关系(图)

    1 为什么用户程序不能直接访问系统内核模式提供的服务 xff1f 在linux中 xff0c 将程序的运行空间分为内核空间与用户空间 xff08 内核态和用户态 xff09 xff0c 在逻辑上它们之间是相互隔离的 xff0c 因此用户程序
  • Linux常用命令(面试版)

    常用指令 span class token function ls span 显示文件或目录 l 列出文件详细信息l span class token punctuation span list span class token punct
  • 带时间窗的车辆路径规划问题(VRPTW)

    车辆路径规划问题是运筹学中经典的NP难问题 xff0c 本文将选取其变种问题 xff0c 结合实际生产中遇到的配送问题进行综合考虑 xff0c 给出了相应的解决算法 一 VRP问题 车辆路径规划问题 Vehicle Routing Prob
  • Matlab 线性规划练习题

    文章目录 Q1Q2Q3Q4Q5 Q1 问题 数学建模某鸡场有1000只鸡 xff0c 用动物饲料和谷物混合喂养 每天每只鸡平均食混合饲料0 5KG xff0c 其中动物饲料所占比例不能少于20 动物饲料每千克0 30元 xff0c 谷物饲料
  • 机器学习 决策树ID3算法 连续值处理

    文章目录 1 开发环境2 1 决策树算法3 1 信息熵3 2 信息增益 一 过程1 计算信息熵2 对连续值进行处理3 选择最优的属性划分4 按照列的属性值划分数据子集4 根据 96 pandas DataFrame类型 96 建立决策树5
  • Python Pandas DataFrame value_counts() 函数 统计属性取值的个数

    文章目录 1 value counts 函数介绍2 统计属性的个数 1 value counts 函数介绍 返回DataFrame数据中其中一列属性取值的个数 比如 xff1a span class token keyword print
  • IDEA FileInputStream 读取文件路径

    文章目录 1 读取绝对路径2 读取相对路径2 1 相对于工程 1 读取绝对路径 相对路径相对于盘符 InputStream re span class token operator 61 span span class token keyw
  • ITK-Snap 处理医疗影像

    文章目录 0 引言1 ITK Snap基本功能1 1 ITK Snap视图介绍1 2 File菜单1 3 Edit编辑菜单1 3 1 个性化标注 1 4 Segmentation 图像标注1 5 Workspace 2 Tool 工具的使用
  • Ubuntu Linux 编译安装的基本步骤

    文章目录 1 基本步骤若报错 xff1a No such file or directory 2 解压 tar bz2文件参考 xff1a 1 基本步骤 解压 xff1a tar zxvf file tar gz 进入解压后的文件夹 xff
  • Ubuntu Linux 安装 QQ音乐打不开的问题

    文章目录 Ubuntu22 04 QQ音乐闪退问题1 修改 desktop 的配置 不生效则重启后生效 Ubuntu22 04 QQ音乐闪退问题 应该是与sandbox有冲突 1 修改 desktop 的配置 span class toke
  • Python os.path.join(a, b) a,b 包含根Linux路径时合并根路径

    文章目录 1 代码 1 代码 span class token operator gt gt span span class token operator gt span a span class token operator 61 spa
  • 推荐几本学uc/os-II的书

    1 xff08 比较难买 xff09 嵌入式实时操作系统uc os II教程 西安电子科技大学出版 这本书对UCOS的源代码分析的非常清楚 比作者原著 在某种程度上要好 xff0c 这本书对关键的代码都给出了流程图 xff01 2 xff0
  • Python os.path.join(a, b) a,b 包含根Linux路径时合并根路径

    文章目录 1 代码 1 代码 span class token operator gt gt span span class token operator gt span a span class token operator 61 spa
  • 1 Mac安装minconda 与 Pytorch

    文章目录 1 miniconda 安装2 配置清华镜像3 下载Pytorch参考 1 miniconda 安装 使用清华镜像 xff1a https mirrors tuna tsinghua edu cn anaconda minicon
  • python:invalid literal for int() with base

    文章目录 1 出现原因2 出现的情景3 解决字符串类型的数据转化 1 出现原因 使用了int 函数且int 转化的对象为非数字型字符串或者浮点型数字字符串 2 出现的情景 数字型字符串无法转化 span class token builti
  • JavaWeb

    JavaWeb Java web 1 基本概念 1 1 前言 web开发 xff1a web xff1a 网页的意思 www baidu com 静态web html Css提供给所有人看的数据始终不会发生变化 xff01 动态web 淘宝