【tomcat】【maven】javaweb笔记

web服务器

ASP:微软推出的服务器技术,最早在国内流行,需要使用C#编写脚本。但是使用ASP写出来的html页面代码极其繁琐,极难维护。维护成本高,重构成本高。

PHP:开发速度非常块比JSP还要块,且写出的html页面代码简洁,能够跨平台。但是无法承载大访问量

JSP/servlet:可以承载三高问题(高并发、高可用、高性能)带来的影响。一般有IIS、Tomcat等服务器。服务器是用来处理用户的请求和给予用户响应的

Tomcat

下载

官网:Apache Tomcat® - Welcome!

选择对应版本下载即可,这里我用的是tomcat9,tomcat10以上的版本跟以往的版本有所不同可能会在学习中出现各种各样的问题,这里建议使用9

tomcat目录结构

【tomcat】【maven】javaweb笔记_第1张图片

可以在bin文件夹找到starup和shutdowm来手动开启或者关闭Tomcat。

可能会遇到的问题

  • 没有配置java的path路径导致starup闪退
  • 闪退:可能是兼容性问题
  • starup乱码:需要修改字符编码,但可能造成IDEA等IDE不能使用Tomcat

服务配置文件

【tomcat】【maven】javaweb笔记_第2张图片

在conf文件夹中的server.xml是核心web服务配置,可以修改端口号,主机名称等等

默认端口号

  • Tomcat:8080
  • http:80
  • Https:443
  • MySQL:3306

问题:如何访问一个网站?

通过URL访问一个网站,首先浏览器会在本机的host文件中去找这个域名对应的IP映射拿到IP地址,分两种情况

  1. 如果拿到了:

    直接向浏览器返回IP地址,浏览器去访问这个IP

  2. 如果没拿到:

    本机向DNS服务器询问,查找这个域名对应的IP地址,找到则返回IP找不到返回404

【tomcat】【maven】javaweb笔记_第3张图片

Http请求


请求行:

  • 请求地址:

  • 请求方式:GET / POST

    get:理论上是无限制的,但是get会在浏览器的URL栏中显示,浏览器一般会对URL做最大限制。所以get实际上能携带参数比较少,数据大小是有限制的,不够安全,但是传输高效

    post:能够携带的参数比较多,数据大小没有限制。不会在浏览器URL中显示,但是可以在请求中抓到传输数据,比较安全,但是传输不高效,

请求头:

Accept:   告诉浏览器它支持的数据类型
Accept-Encoding: 支持的编码格式  GBK、UTF-8、bg2312……
Accept-Language: 告诉浏览器它的语言环境
Cache-Control: 缓存控制
Connection: 连接状态
Refresh:告诉浏览器多久刷新一次
Location:让网页重新定位

状态码:

200 OK:表示请求成功

3XX:表示重定向

404:未找到资源

5XX:服务器代码错误

  • 502:网关错误

常见面试题:当你在浏览器地址栏输入URL的一瞬间到页面展示完成,其中经历了什么?

Maven:


Maven是一个项目架构管理工具,在Javaweb开发中,我们一般用它来导入jar包和配置一些东西。

核心思想:约定大于配置!(就是有约束)

Maven会规定我们如何去编写Java代码,必须按照规范

Maven需要配置环境变量:

在这里插入图片描述

在系统path中配置:

image-20220308153604591

最后提一下,M2_HOME的配置是为了能够适应后面springboot等框架的自动开发。maven版本和idea版本存在兼容性问题,我使用的是2020.2兼容的是maven3.6.3之前的版本

配置maven阿里云镜像:
作用是可以加速我们下载东西的速度

【tomcat】【maven】javaweb笔记_第4张图片

新建本地仓库:

首先在maven目录下新建一个maven-repo文件夹,如何在conf配置文件里的setting配置:

【tomcat】【maven】javaweb笔记_第5张图片

IDEA / Eclipse创建MavenWeb项目:


IDEA新建MavenWeb项目:

1、选中这三个如何点击next

creat from archetype的意思是可以使用一些别人写好的模板

【tomcat】【maven】javaweb笔记_第6张图片

2、给项目命名,填如组id,选择项目保存路径,然后点击next

【tomcat】【maven】javaweb笔记_第7张图片

3、选择你的maven目录然后next

小小补充一下:IDEA集成了maven可以在这里选择,但是一般我们用自己的。

【tomcat】【maven】javaweb笔记_第8张图片

4、最后点击finish即可,然后idea会帮我们创建好项目,第一次创建可能需要一段时间,耐心等待IDEA右下角进度条跑完。

4.1、补充:这个警告的意思是没有在网络上找到模板,默认使用内部模板。在这一步可能会有小伙伴的IDEA提示警告,没有警告的小伙伴可以跳过。(其实可以不管)

在这里插入图片描述

这里需要我们手动下载 archetype-catalog.xml文件,放在本地仓库的根路径下。教程参考:https://blog.csdn.net/fyydashen/article/details/105921518

最后设置完毕之后重新创建项目在第三步的下边新建一项:键为archetypeCatalog,值为internal。

【tomcat】【maven】javaweb笔记_第9张图片

5、创建好之后,在右下角会有一个提示我们点击enable auto-import

【tomcat】【maven】javaweb笔记_第10张图片

如果没用弹出这个提示我们也可以从idea的设置里面找到File->Settings->Maven->Importing->Import Maven projects automatically

不过在idea2020之后的版本都取消了这个设置,使用2020之后的版本的小伙伴可以不用管

6、至此,使用模板创建Maven项目就已经完成了。

补充:使用模板创建的javaweb项目缺少两个重要的文件,需要手动创建,在main文件夹下面创建Java文件夹和resource文件夹。IDEA在我们创建的这个模板项目中new文件夹可以直接选中相应的文件夹。

如何没有选中,可以直接new文件夹,new出来的文件夹要选择类型

【tomcat】【maven】javaweb笔记_第11张图片

IDEA新建普通的Maven项目:

和创建Maven的模板一样只是我们不勾选creat from archetype

创建之后的目录结构是:

【tomcat】【maven】javaweb笔记_第12张图片

Eclipse创建maven项目:

推荐一篇教程:https://blog.csdn.net/u012052268/article/details/78916196#13_44

maven项目配置Tomacat服务器:


点击这个idea右上角的add……

在这里插入图片描述

点左上角的加号然后在下拉框找到Tomcat server,local代表使用本地Tomcat,Remote代表使用远程,这里我们使用本地

【tomcat】【maven】javaweb笔记_第13张图片

然后如图配置。警告的原因是因为IDEA无法识别到我们Tomcat里的webAPP文件夹,服务器运行时无法访问站点,我们需要在idea里配置这样一个东西,而且是必须配置

【tomcat】【maven】javaweb笔记_第14张图片

然后跳转到Deployment选项卡,我们点击+新建,点击第一个选项然后apply然后点OK即可

【tomcat】【maven】javaweb笔记_第15张图片

这时候右上角Tomcat就亮起来了,如果没有就继续点击edit然后在Templates中找到Tomcat server中的local修改里面的Deployment选中我们刚刚添加的文件点击edit按钮(一个笔),然后设置为我们自己的项目

【tomcat】【maven】javaweb笔记_第16张图片

至此就配置好我们idea中的tomcat服务器了,点击运行看到有红色字体或者乱码出现随后就会弹出你第一个网页。

image-20220309202714282

【tomcat】【maven】javaweb笔记_第17张图片

POM.xml文件:

【tomcat】【maven】javaweb笔记_第18张图片

tomcat运行成功后会创建一个target文件夹用来存放网站,web-inf下会自动创建一个lib目录用来存放一些依赖(jar包)这是maven自动帮我们导入的

【tomcat】【maven】javaweb笔记_第19张图片

【tomcat】【maven】javaweb笔记_第20张图片

补充:jar是Java的打包方式,war是javaweb的打包方式

这里,dependencies是项目依赖,我们可以到在线的maven仓库中找到我们需要的jar包,然后将它的dependency的代码拷贝到这里,然后maven项目会自动的帮我们导入jar包,不需要我们手动下载

**但是!**这还不是maven最高级的地方,它最高级的地方就在于,maven可以帮我们导入我们导入的jar包所依赖的jar包,意思就是这个jar包用了其他jar包,我们用了这个jar包,maven会帮助我们导入这个jar包用的其他jar包。

【tomcat】【maven】javaweb笔记_第21张图片

maven存在的问题:

maven在导出资源可能会遇到,文件导出失败或者无法生效的问题。这是由于maven约定大于配置造成的。

解决方案:

在pom.xml文件中配置build,这是个固定写法,可以用来解决资源导出问题

  <build>
      <resources>
        <resource>
            <directory>src/main/resourcesdirectory>
            <excludes>
                <exclude>**/*.propertiesexclude>
                <exclude>**/*.xmlexclude>
             excludes>
            <filtering>falsefiltering>
        resource>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>falsefiltering>
        resource>
    resources>
build>

可能在maven中遇到的问题:


首先说一下:使用低版本的maven和jdk和ide加上正确的操作可以解决90%以上的问题

  1. maven3.6.2无法导入依赖:它会报一个这样的错,使用低一个版本的maven3.6.1就好,这需要我们重新配置本地仓库和阿里云然后修改环境变量

    在这里插入图片描述

  2. Tomcat闪退:有可能是端口被占用,然后就是你的JAVA_HOME和JRE_HOME可能没有配置好

  3. idea中每次都要重复配置maven

    在idea中配置全局配置

    首先选中file–>选中close object然后在选择configure选择setting

    【tomcat】【maven】javaweb笔记_第22张图片

    然后把你的设置修改到你本地的设置

    【tomcat】【maven】javaweb笔记_第23张图片

  4. idea中tomcat无法配置

  5. maven默认web项目中web.xml版本问题。

    这个,我们可以去tomcat目录中webapps\ROOT\WEB-INF中找到web.xml,将里面的内容替换到我们项目中的web.xml中

    <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>
    

使用maven在线仓库:

在某些情况下,我们可用使用本地仓库导入项目依赖,但有时可能找不到我们想要的jar包,这个时候我们就可以去maven的在想仓库中去找

maven仓库:https://mvnrepository.com/

在maven仓库找到我们想要的jar包之后把它的maven代码复制到我们的pom.xml中,大概是原本的dependencies上面

【tomcat】【maven】javaweb笔记_第24张图片

查看我们的maven,确实是导入进来的

【tomcat】【maven】javaweb笔记_第25张图片

然后再导一下包就行了

【tomcat】【maven】javaweb笔记_第26张图片

先简单写一个例子,这个例子可以在tomcat页面中的example中拿到

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
        doGet(req,resp);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
        //响应类型
        resp.setContentType("text/html");
        //获取响应的输出流
        PrintWriter out = resp.getWriter();
        out.println("");
        out.println("");
        out.println("hello,world!");
        out.println("");
        out.println("");
        out.println("

hello,world!

"
); out.println(""); out.println(""); } }

然后在web.xml中注册我们的写好的servlet

<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">

    <servlet>
        <servlet-name>helloservlet-name>
        <servlet-class>HelloServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
web-app>

启动tomcat在地址栏输入我们配置的url-patter即可

servlet:


首先,什么是servlet?

把实现了servlet接口的Java程序就叫做servlet。

开发一个servlet需要两步:

  1. 编写一个类实现servlet接口
  2. 将开发好的Java类部署到web服务器中

在idea里不使用模板创建一个普通的maven项目,把src目录删除,创建moudel文件夹(这个叫做模块,这里我们把它当作子项目来开发),之后的学习都使用moudel来创建。

首先在pom.xml文件中导入jsp需要的依赖,或者在之后的学习中让idea帮我们导入依赖,这就需要遇到问题再来导入了 。这里可以先导入servlet和jsp,后面的jstl和standrd会在之后的学习中碰到

    <dependencies>	       

        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>4.0.1version>  
            <scope>providedscope>
        dependency>
        
        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>javax.servlet.jsp-apiartifactId>
            <version>2.2.1version>
            <scope>providedscope>
        dependency>
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>
        
        <dependency>
            <groupId>taglibsgroupId>
            <artifactId>standardartifactId>
            <version>1.1.2version>
        dependency>
    dependencies>

之后我们创建一个moudel使用maven的webapp模板,创建完毕之后可以看到子项目中的maven和父项目中的maven出现了新的东西

    <modules>
        <module>servlet-01module>
    modules>

 <parent>
        <artifactId>javaweb-servlet-testartifactId>
        <groupId>org.examplegroupId>
        <version>1.0-SNAPSHOTversion>
    parent>

如何将我们拿到的maven项目模板的环境优化一以下

  1. 修改web.xml为最新
  2. 在main中创建我们的Java和resource目录

一般情况只要实现servlet接口即可视为创建了一个servlet程序,但是servlet有两个默认的实现类httpservletGenericServlet我们只需要继承它们其中一个就好。

一般我们实现doget和dopost方法就好,这两种方法请求实现的方式不同可以相互调用,业务逻辑是一样的。做好一个servlet程序之后,我们要在项目web.xml注册这个servlet程序,接着我们配置tomcat。

servlet原理:


浏览器通过http发送请求到服务器,服务器拿到请求之后拆解请求头和请求体,接着将请求的信息传递给我们的servlet的request,我们实现service,然后将处理好的信息通过response传递给前端

servlet中的mapping问题:


一个servlet可以指定一个映射路径:

可以指定多个映射路径:

可以指定通用映射路径:/*

可以带上前缀或者后缀:*.sdahdhs等等

优先级问题;

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

注解配置:

普通的servlet可以使用注解的方式进行配置,本质上用的Java的映射。需要在servlet3.0和tomcat7.0以上的版本才能支持注解配置。

在类名前一行@WebServlet(“/路径”)

ServletContext:


在web应用中,每个servlet都是相互独立的。ServletContext可以保存servlet程序的一些东西,通过ServletContext可以做到servlet程序之间的相互通信.web容器启动的时候会为每个web程序都创建一个对应的ServletContext对象

  • 共享数据

    public class GetServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext servletContext = this.getServletContext();
            resp.setContentType("text/html;charset=utf-8");
            String suid = String.valueOf(servletContext.getAttribute("suid"));
            resp.getWriter().print("姓名"+suid);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("hello!");
            ServletContext servletContext = this.getServletContext();
            String username = "aaa";
            servletContext.setAttribute("suid",username);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 配置web.xml

    <servlet>
        <servlet-name>helloServletservlet-name>
        <servlet-class>com.zhong.servlet.HelloServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>helloServletservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    <servlet>
        <servlet-name>getServletservlet-name>
        <servlet-class>com.zhong.servlet.GetServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>getServletservlet-name>
        <url-pattern>/hello1url-pattern>
    servlet-mapping>
    

获得初始参数:

getinitparameter()方法可以从web.xml中拿到一些初始化的参数

请求转发:

使用servletContext.getRequestDispatcher();方法进行转发,参数填入转发路径即可,然后.forward(),参数填入req和reps。

注意区别转发和重定向,转发是请亲路径不会改变,返回状态码200,你请求的路径页面会帮你从其他地方转发资源过来显示。重定向是,你请求的路径页面会告诉你一个新的路径然后浏览器帮你重新进入新的路径页面,所以url会改变,返回状态码3XX

properties:

读取资源文件

一般来说properties资源文件一般放在resource文件夹下,但也有放在Java文件夹下的。如果是resource文件夹下可以正常从maven中导出,但是在Java文件夹下的properties文件是无法正常导出的,需要配置build。然后this.getServletContext().getResourceAsStream("/WEB-INF/classes/gb.properties");如果参数路径没有被找到,那么将会返回500服务器内部错误状态码。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/gb.properties");
    Properties prop = new Properties();
    prop.load(is);
    String username = prop.getProperty("username");
    String password = prop.getProperty("password");
    resp.getWriter().print(username+":"+password);
}
username=123456
password=abc

HttpServletResponse:

客户端发送http请求,然后web服务器会针对请求创建两个对象HttpServletResponse和HttpServletRequest,一些在http中附带的参数在HttpServletResponse中获取,响应回去的信息写在HttpServletRequest中

负责向浏览器发送数据:

ServletOutputStream getOutputStream() throws IOException;//一般来说写平常的流使用这个方法

PrintWriter getWriter() throws IOException;//写中文的时候会用这个方法

发送响应头:

void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

void setDateHeader(String var1, long var2);

void addDateHeader(String var1, long var2);

void setHeader(String var1, String var2);

void addHeader(String var1, String var2);

void setIntHeader(String var1, int var2);

void addIntHeader(String var1, int var2);

void setStatus(int var1);
下载文件

1、获取文件的下载路径

2、获取文件名

3、让浏览器支持我们下载的东西

4、获取文件的输入流,将文件拿到Java代码中

5、创建缓冲区

6、获取resp的输出流

7、将Java中的文件输出到响应

//1、获取文件的下载路径
String path = "D:\\sourceCode\\servlet\\response-download\\src\\main\\resources\\喵.jpg";
//2、获取文件名
String fileName = path.substring((path.lastIndexOf('\\')) + 1);//将路径中最后一个/的下标返回然后从这个下标的后一位开始截取子串
//3、让浏览器支持我们下载的东西
resp.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "utf-8"));// 固定写法  使用URLEncoder解决中文乱码问题
//4、获取文件的输入流,将文件拿到Java代码中
FileInputStream in = new FileInputStream(path);
//5、创建缓冲区
int len;
byte[] buffer = new byte[1024];
//6、获取resp的输出流
ServletOutputStream out = resp.getOutputStream();
//7、将Java中的文件输出到响应
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}
//8、关闭流
out.close();
in.close();
验证码功能:
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //让浏览器每隔多少秒就刷新一次
        resp.setHeader("refresh","5");


        //首先,在内存中创建一张空白的图,并指定图片颜色显示RGB三原色
        BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //拿到这张图的画笔,设置画笔的颜色为白色,用画笔填充整张图片为白色
        Graphics graphics = bufferedImage.getGraphics();
        graphics.setColor(Color.white);
        graphics.fillRect(0,0,80,20);
        //再次设置画笔的颜色,写字需要给画笔设置字体
        graphics.setColor(Color.blue);
        graphics.setFont(new Font(null,Font.BOLD,20));
        graphics.drawString(makeNumber(),0,20);//设置好画笔之后,将要写的数据传入画笔的drawxxxxx方法中
        //设置响应的头,告诉浏览器这个请求用图片方式打开
        resp.setContentType("image/jpeg");
        //让浏览器不缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-Cache");
        resp.setHeader("Pragma","no-Cache");

        ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());

    }

    private String makeNumber() {
        Random random = new Random();//创建一个随机数生成器
        String num = random.nextInt(9999999) + "";//通过nextint方法指定随机数生成的范围,但是有可能达不到我们要求的7位数
        StringBuffer stringBuffer = new StringBuffer();//接下来处理缺少的位,创建一个StringBuffer方便我们对缺少的位追加0
        for (int i = 0; i < 7 - num.length(); i++) {
            //检测缺少几位,就追加几个0
            stringBuffer.append("0");
        }
        num = stringBuffer.toString() + num;//通过拼接字符串来对前面缺少的位补0
        return num;
    }

Response实现重定向

一般常见在用户登陆这种场景中实现

void sendRedirect(String var1) throws IOException;
/* resp.setHeader("Location","/r1/image");
 resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);*/
resp.sendRedirect("/r1/image");

${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> 。取得当前项目的绝对地址

HttpServletRequest:

获取前端传递的参数,请求转发:

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.util.Arrays;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码问题
        //让请求和响应都为utf-8,此后此操作将会在过滤器中实现
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String userName = req.getParameter("userName");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");
        String[] sexes = req.getParameterValues("sex");
        System.out.println("============================");
        System.out.println(userName);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println(Arrays.toString(sexes));
        System.out.println("============================");
        //这是通过响应进行重定向
        //        resp.sendRedirect("/");
        //这是通过请求,将这个请求转发
        //在jsp中通过动作元素实现
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    登陆


用户名:
密码:
爱好: 乒乓球 羽毛球 篮球 足球
性别:

cookie:

会话:用户打开浏览器进行操作一直到关闭浏览器的这个过程叫做会话

有状态会话:当客户端连接过服务器之后,下一次客户端连接时,服务器可以知道这个客户端上一次连结过。

区别:

session:保存在服务器,大小无限制,可以存储任意类型,有效期默认保存30分钟

cookie:保存在客户端,大小一般不超过4KB,只能存储键值对的字符串类型,有效期是会话

  • cookie是客户端技术
  • 服务器技术,可以保存用户的会话信息

常见场景:一般用户在登陆网站之后,可以不用再进行登陆,第二次访问是已经登陆的状态

//解决中文乱码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//通过request拿到一个cookie的数组
Cookie[] cookies = req.getCookies();
//获得cookie中的key
cookie.getName();
//获得cookie中的value
cookie.getValue();
//创建一个cookie
Cookie cookie = new Cookie("lastTime", System.currentTimeMillis() + "");
//设置cookie的有效期
cookie.setMaxAge(24*60*60);
//通过responds返回一个cookie
resp.addCookie(cookie);

cookie一般保存在本地

  • 一个cookie只能保存一个信息
  • 一个web站点可以发送多个cookie,一个web站点最多存放20个cookie
  • 浏览器存放cookie的上线是300个
  • cookie的大小是4KB

删除cookie

  • 在一个正常的cookie中,不设置cookie的有效期,关闭浏览器后自动失效
  • 创建一个新的同名cookie,设置它的有效期为0,将这个cookie返回给浏览器。由于cookie使用键值对,key唯一,出现同名key时将替换。

中文存储cookie问题

在cookie中可能存在中文乱码或者中文的value取不出来的问题,在这里使用编码解码的方式可以解决

URLEncoder.encode("值","utf-8");//给字符编码
URLDecoder.decode("值","utf-8");//给字符解码 

session(重点):

  • 服务器会给每一个用户(或者说叫做浏览器)创建一个session对象

  • 一个浏览器窗口对应一个session,只要浏览器不关闭,session一直存在

    猜想:一个服务器对一个一个session,每个站点保存的session都不同,且互不干扰

    猜想2:用户信息保存在session中,那么打开两个浏览器窗口就对应两个session,第二个浏览器窗口需要重新登陆,用户登陆之后,以已登陆的状态可以访问整个网站 session一般用于保存用户信息或者购物车等

  • session创建的时候会通过response返回一个叫做JsessionID的cookie,每次浏览器request的时候都会带上这个cookie

  • cookie是把用户的数据写给浏览器,让浏览器来保存(可以写多个)

  • session把用户数据写到一个用户独占的session中,服务器来保存(一般只保存重要的信息,避免服务器资源浪费)

  • session对象由服务器创建

使用场景:

  • 保存一个登陆用户的信息
  • 购物车信息
  • 整个网站经常会用到的信息
//解决中文乱码
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的id
String id = session.getId();
//判断session是不是新创建的
if (session.isNew()) {
    System.out.println(id + "是新创建的");
} else {
    System.out.println(id + "不是新创建的");
}
//拿到session中的值
session.getAttribute("name");

//手动注销session
session.removeAttribute("name");
session.invalidate();
// 由服务器来注销session在web.xml中实现

session自动过期


<session-config>
    
    <session-timeout>1session-timeout>
session-config>

JSP:


JSP本质上就是Servlet

jsp转换成的java文件放在这个地方,一般只有一个index,当启动tomcat访问到其他的jsp文件时才会创建其他对应的Java文件,这个路径可能会存在部分差异

C:\Users\你系统当前的用户名\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\Unnamed_javaweb-session-cookie_2\work\Catalina\localhost\ROOT\org\apache\jsp

当maven导入不了我们需要的依赖时,可以使用tomcat中的lib目录作为我们的库。

打开当前项目的项目结构,找到libraries点击加号,选择java,然后找到tomcat的lib目录点击OK,点击右下角的apply即可

//初始化
public void _jspInit() {}
//销毁
public void _jspDestroy() {}
//jspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

内置对象:

final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContext application;//applicationContext
final javax.servlet.ServletConfig config;//config
javax.servlet.jsp.JspWriter out = null;//out
final java.lang.Object page = this;//page
HttpServletRequest request;
HttpServletResponse response;

JSP基础语法:

JSP表达式:

<%-- 用来将程序的结果输出到客户端 --%>
<%=  %>

<%-- jsp脚本片段,一般用来写Java代码 --%>
<%  %>

<%-- jsp声明,一般用来声明一些方法,此声明可以将尖括号内的内容放进servlet类下,而不是service方法中--%>
<%! %>

EL表达式
${}

定制错误页面:

<%@ page errorPage="URL"%>

或者,我们可以在web.xml中配置错误页面

<error-page>
    <error-code>404error-code>
    <location>/error/404.jsplocation>
error-page>
<%@ pageEncoding="utf-8"%>
<%-- 声明当前页面的编码 --%>

JSP指令:

<%@ page args....%>
<%-- 将某个页面静态的包含进来,这是属于编译层面的事情,在将jsp文件翻译成servlet文件的时候就已经包含进来其他页面的内容,在其他页面我们既可以使用HTML标准结构也可以不使用。这里推荐直接写HTML标签而不使用html结构 --%>
<%@include file="XXX.jsp"%>

JSP标签:

<%-- 这是动态包含,一般需要写html结构,这是在浏览器层面进行的包含
    --%>

JSP九大对象:

  • PageContext
  • Request
  • Response
  • Session
  • Application 【ServletContext】
  • config 【ServletConfig】
  • out
  • page
  • exception

使用四种内置对象存入数据,使用pageContext取出当前页面的存入的数据,使用EL表达式将数据输出

<%
pageContext.setAttribute("name1", "1");
request.setAttribute("name2", "2");
session.setAttribute("name3", "3");
application.setAttribute("name4", "4");
%>

<%
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");
%>
<%-- ${}等值于<%=%> --%>

输出的值是:

${name1}

${name2}

${name3}

${name4}

${name5}

EL表达式对于<%=%>的优点就在于,当值为空时,EL表达式不显示取值,而<%=%>将显示null。

页面转发:

<%
    pageContext.forward("/XXX.jsp");
    request.getRequestDispatcher("XXX.jsp").forward(request,response);
%>

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

需要导入两个jar包:


<dependency>
    <groupId>javax.servlet.jsp.jstlgroupId>
    <artifactId>jstl-apiartifactId>
    <version>1.2version>
dependency>

<dependency>
    <groupId>taglibsgroupId>
    <artifactId>standardartifactId>
    <version>1.1.2version>
dependency>

EL表达式:$ { }

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

JSP标签:




    
    

JSTL标签:

这是一个第三方的组件库,JSTL的标签使用分装了一些我们常用的Java程序,便于我们使用。JSTL标签就是通过自定义标签来实现的。JSTL的使用需要引入一个头。

jstl标签有几个库组成:

  • 核心标签

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  • 格式化标签

  • SQL 标签

  • XML 标签

EL表达式获取表单中的数据:

${param.参数名}


这里提一个小问题:

使用JSTL标签,在IDEA发布项目的会报一个500的错。这时候,我们需要将maven导入的jstl包和standard包复制一份到tomcat的lib目录下即可

JavaBean:

就是实体类

Javabean有特定的写法:

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

符合这种特定写法的,就可以称作JavaBean

一般用来映射数据库(用来和数据库字段做映射)

ORM:对象关系映射

  • 表—>类
  • 字段—>属性
  • 行记录—>对象(实例)
<%
	new people();
%>



MVC三层架构:

早年的两层架构:

MVC:模型视图控制器

三层架构是为了开发出来的项目易于维护而制定的一些规范

servlet专注于处理请求以及控制视图跳转

JSP专注于显示数据

控制器controller(servlet):

  • 接收用户的请求
  • 响应给客户端内容
  • 重定向或者转发

视图层view(JSP):

  • 展示数据
  • 提供可以供我们操作的请求

三层(包含model):

控制器controller(servlet):

  • 接收用户请求
  • 请求交给业务层(接收返回的数据)
  • 视图跳转

视图层view(JSP):

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

model层:

控制业务操作、CRUD等等

这一层包含三个块

  1. service(业务层)与控制器层打交道
    • 一般包含login、logout、查询等等
  2. pojo(entity)实体层
  3. dao层(数据持久层)(一般和业务层打交道)操作数据库

【tomcat】【maven】javaweb笔记_第27张图片

【tomcat】【maven】javaweb笔记_第28张图片

Filter过滤器:

过滤器就是用来过滤网站的数据的

处理乱码问题、登陆验证

首先,在一个新项目中导包:

<dependencies>
    <dependency>
        <groupId>javax.servletgroupId>
        <artifactId>servlet-apiartifactId>
        <version>2.5version>
    dependency>
    <dependency>
        <groupId>javax.servlet.jspgroupId>
        <artifactId>javax.servlet.jsp-apiartifactId>
        <version>2.3.3version>
    dependency>
    <dependency>
        <groupId>javax.servlet.jsp.jstlgroupId>
        <artifactId>jstl-apiartifactId>
        <version>1.2version>
    dependency>
    <dependency>
        <groupId>taglibsgroupId>
        <artifactId>standardartifactId>
        <version>1.1.2version>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.47version>
    dependency>
dependencies>

编写过滤器(其实就是写servlet):

  1. 实现servlet内的filter接口(javax.servlet.Filter),并且重写三个方法

    package com.zhong.filter;
    import javax.servlet.*;
    import java.io.IOException;
    
    public class CharacterEncodingFilter implements Filter {
        //过滤器在web服务启动的时候就会初始化,因为到等待过滤对象出现
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("过滤器初始化");
        }
        //chain是链的意思,有过滤器链
        //过滤器中的所有代码,在过滤特定请求的的时候都会执行
        //必须要让过滤器通行,写dofilter
        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("过滤器执行前");//这里是固定写法,转交请求,如果还有过滤器则转交给过滤器,没有则交给servlet
            filterChain.doFilter(servletRequest,servletResponse);
            System.out.println("过滤器执行后");
        }
        //关闭服务器时销毁过滤器
        public void destroy() {
            System.out.println("过滤器销毁");
        }
    }
    
    

配置filter过滤器

<filter>
        <filter-name>CharacterEncodingFilterfilter-name>
        <filter-class>com.zhong.filter.CharacterEncodingFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>
        <url-pattern>/servlet/*url-pattern>
    filter-mapping>

监听器:

监听器在javaweb项目中用的越来越少了

实现监听器接口(有N种接口)

1.实现监听器接口

//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {
    //一旦创建一次session就会触发一次事件
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println(httpSessionEvent.getSession().getId());
        ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");

        if (onlineCount == null) {
            onlineCount = new Integer(1);
        } else {
            int i = onlineCount.intValue();
            onlineCount = new Integer(i + 1);
        }
        servletContext.setAttribute("onlineCount", onlineCount);
    }

    //一旦销毁一次session就会触发一次事件
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
        if (onlineCount == null) {
            onlineCount = new Integer(0);
        } else {
            int i = onlineCount.intValue();
            onlineCount = new Integer(i - 1);
        }
        servletContext.setAttribute("onlineCount", onlineCount);
    }
}
  1. 注册监听器

    <listener>
        <listener-class>com.zhong.listener.OnlineCountListenerlistener-class>
    listener>
    

过滤器监听器常见应用

GUI编程中经常使用监听器

过滤器:
实现用户登陆之后才能进入主页,不登录无法进入主页

  1. 用户登陆之后,向session中存放用户数据
  2. 进入主页的时候判断用户是否已经登陆;在过滤器中实现
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest servletRequest1 = (HttpServletRequest) servletRequest;
    HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse;
    if (servletRequest1.getSession().getAttribute("USER_SESSION")==null) {
        servletResponse1.sendRedirect("/err/error.jsp");
    }

    filterChain.doFilter(servletRequest,servletResponse);
}

这里提供另外一种思路,将页面放入WEB—INFO文件夹下,然后web.xml中设置欢迎页,其他请求都通过转发来跳转页面

回顾JDBC:

首先,JDBC是一组接口它统一了不同厂商的数据库的驱动。

连接数据库,首先可以使用idea中的databese,填好账户名和密码和连接的数据库即可

在Java类中连接数据库一般是,先写url和用户米、密码。这里加载驱动的方式有两种,一种是通过反射,另一种是通过drivermanager加载。我们用反射去加载,更快。

事务:

要么都成功,要么都失败

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

Junit jar包

可以让程序进行单元测试,让程序不需要从main方法的入口也能够运行

依赖


<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
dependency>

使用

在需要测试的方法中添加注解@Test即可

import org.junit.Test;

public class PrintHello {	
    @Test
    public void print(){
        System.out.println("hello");
    }
}

你可能感兴趣的:(笔记,tomcat,maven,servlet,web,mvc)