JavaWeb

JavaWeb包括:Tomcat、HTTP、Maven、Servlet、Cookie、Session、JSP、JDBC。

JavaWeb

在这里插入图片描述

1.1 什么是JavaWeb

  • web:网页的意思
  • 在Java中,动态web资源开发的技术统称为JavaWeb
  • 静态web:每个人看的内容都相同
  • 动态web:不同的人在同样的时间看到的内容都不相同

1.1.1 静态Web

  • .htm,.html这些都是网页的后缀,服务器中的这些资源可以通过网络直接读取

静态web存在的缺点

  • web页面无法动态更新,所有用户看到的都是同一个页面
  • 轮播图,点击特效。(伪动态)
  • JavaScript: 它无法和数据库交互(数据无法持久化,用户无法和电脑交互)

1.1.2 动态Web

  • web服务器先将请求数据中的动态资源转换为静态资源后,再响应给前端页面展示。

  • 页面会动态展示:web页面展示效果因人而异

动态web存在的缺点

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

动态web存在的优点

  • web页面可以动态更新,所有用户看到的页面都不相同
  • 可以和数据库交互(数据持久化:注册,用户信息)

1.2 Web应用程序

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

  • a.html…多个web资源,可以被外界访问, 对外界提供服务
  • 能访问的任何一个页面或资源,都存在某一台计算机中
  • 通过URL来或者这个资源
  • 这个统一的web资源会放在同一个文件夹下,web应用程序–TomCat
  • 一个web应用应该由多部分组成(静态web,动态web)
    • html,css,js
    • jsp,servlrt
    • java程序
    • jar包
    • 配置文件(xml,properties)

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

1.3 Web服务器

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

Tomcat

2.1 安装Tomcat

windows系统在这里插入图片描述
开启服务器后测试 :http://localhost:8080/

出现该页面表示服务器启动成功

在这里插入图片描述
可能遇到的问题

  • Java环境变量没有配置(JAVA_HOME)
  • 闪退问题:需要配置兼容性
  • 乱码问题:配置文件中设置

2.2 配置Tomcat

核心配置文件
在这里插入图片描述
配置启动的端口号(8080)

 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

配置主机的名称(localhost)

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

网站是如何进行访问的?

  1. 输入一个域名(对应的一个ip地址),回车
  2. 先检查本机的C:\Windows\System32\drivers\etc\host配置文件下有没有这个域名映射;
    • 有:直接返回对应的ip地址,这个地址中有需要访问的web程序,可以直接访问。
    • 没有:去DNS服务器找,找到的话就返回ip地址,找不到就返回找不到该页面。(DNS:管理着全世界的域名)

2.3 发布一个Web网站

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

一个web项目的目录结构

-- webapps :tomcat服务器的web目录
	--ROOT:默认项目目录
	--rm:自己网站的目录名
		--WEB-INF
			--classes:java程序
			--lib:web应用所依赖的jar包
			--web.xml:配置文件
		--index.html 默认的网站首页
		--static:静态资源目录
			-css
			-js
			-img

HTTP

参考图解HTTP这一博文。

3.1 什么是HTTP

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

  • 文本:html,文字…
  • 超文本:图片,视频,定位,地图…
  • 默认80端口

HTTPS(安全的超文本传输协议)

  • 默认443端口
  • S:safe

3.2 HTTP的两个时代

  • HTTP/1.0:每一次请求响应都会建立新的连接,比较耗时和浪费资源

  • HTTP/1.1:复用连接,当第一次请求结束后,会等待一会看是否有新的请求,如果有,则复用这次申请的连接,直到没有请求数据发送为止

3.3 HTTP请求

客户端–发请求–服务器

请求行

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

消息头

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

3.4 HTTP响应

  • 服务器–响应–客户端

响应体

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

响应状态码

协议/版本    响应状态码  状态码描述
HTTP/1.1     200     OK

响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
1. 状态码都是3位数字 
2. 分类:
	1. 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码
	2. 2xx:成功。代表:200
	3. 3xx:重定向。代表:302(重定向)304(访问缓存)
	4. 4xx:客户端错误。
		* 404(请求路径没有对应的资源) 
		* 405:请求方式没有对应的doXxx方法
	5. 5xx:服务器端错误。代表:500(服务器内部出现异常)502(网关错误)

Maven

  • Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
  • 在JavaWeb开发中,需要使用大量的jar包,需要手动导入, Maven能够自动导入和配置这些jar包

4.1 Maven的下载

下载地址:https://maven.apache.org/download.cgi
在这里插入图片描述

  • 解压到一个专门放环境变量的文件夹中

在这里插入图片描述

4.2 Maven配置

4.2.1 配置Maven环境变量

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2.2 配置本地仓库

在setting中配置本地仓库
在这里插入图片描述

4.2.3 配置阿里云镜像

  • 作用:加速下载jar包

在setting中配置阿里云镜像

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

4.2.4 在IDEA中配置Maven

在这里插入图片描述

为以后新建的项目配置Maven
在这里插入图片描述

4.3 Maven静态资源导出问题

<build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

4.4 在IDEA中使用Maven

创建一个MavenWeb项目

在这里插入图片描述

在这里插入图片描述

创建好的web项目目录结构

在这里插入图片描述

普通的maven项目目录结构

在这里插入图片描述
手动补齐web项目目录

  • 在main目录下新建一个java和resouce目录,在src下新建一个test目录,test目录里面再新建一个java目录。并为其赋予属性

在这里插入图片描述

补齐后的一个完整的web项目目录结构

在这里插入图片描述

4.5 在IDEA中配置Tomcat

在这里插入图片描述

在这里插入图片描述

虚拟路径映射
在这里插入图片描述

4.6 Pom.xml文件

  • Maven项目的核心配置文件
4.6.1 查看导入的jar包体系结构树图

在这里插入图片描述
在这里插入图片描述

Servlet

5.1 什么是Servlet

  • Servlet就是sun公司开发动态web的一门技术
  • Sun公司在这些API中提供了一个接口叫做Servlet
  • 实现了Servlet接口的程序叫做Servlet
  • 编写一个类继承Servlet接口
  • 把开发好的Java类部署到web服务器中

5.2 创建一个Servlet

Servlet接口有两个默认的实现类:HttpServletGenericServlet

5.2.1 创建Maven工程

  • 构建一个普通的Maven项目

  • 删除src目录,这个空的工程就是主工程

  • 在这个项目中创建module

  • Maven父子工程(主项目和module模块)

  • 注意: 父项目中的依赖子项目可以直接使用

父项目中

<modules>
    <module>servlet01</module>
</modules>

子项目中

<parent>
    <artifactId>MyServlet</artifactId>
    <groupId>com.rm</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

5.2.2 创建类继承HttpServlet

  • 创建一个类继承HttpServlet,重写doPost,doGet方法
  • 由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样
public class servlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();//响应字节输出流
        writer.write("Hello,Servlet");
    }

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

5.2.3 配置Servlet映射

  • 在web.xml中配置servlet映射
  • 为什么需要映射: 我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以需要在web服务器中注册我们写的servlet,还需要指定一个浏览器能够访问的路径。
  <servlet>
    <servlet-name>servlet01</servlet-name>
    <servlet-class>com.rm.servlet.servlet01</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>servlet01</servlet-name>
    <!--配置servlet访问路径-->
    <url-pattern>/servlet</url-pattern>
  </servlet-mapping>

5.2.4 测试

  • 启动tomcat服务器,在浏览器地址栏输入http://localhost:80/servlet

在这里插入图片描述

5.2.5 servlet执行原理

  • 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
  • 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
  • 如果有,则在找到对应的<servlet-class>全类名
  • tomcat会将字节码文件加载进内存,并且创建其对象
  • 调用其方法

5.3 Servlet原理

  • Servlet是由web服务器调用,web服务器在接收到浏览器请求后:

在这里插入图片描述

5.4 Mapping问题

  1. 一个Servlet可以指定一个或多个映射路径。(/aaa,/aa,/bb)
  2. 一个Servlet可以指定通用映射路径
  3. 可以在映射路径中指定一些前缀或者后缀(通配符)

优先级问题:
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
/ *表示默认的处理请求

  <servlet>
    <servlet-name>servlet01</servlet-name>
    <servlet-class>com.rm.servlet.servlet01</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>servlet01</servlet-name>
    <!--/*表示默认的处理请求-->
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

5.5 ServletContext对象

  • web容器在启动的时候,会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用。(全局唯一)

5.5.1 共享数据

  • 共享数据(在一个Servlet中保存的数据,可以在另一个Servlet中获取)

  • 先访问存放数据的servlet,再访问获取数据的servlet才能成功获取数据。

存放数据的Servlet类

public class setServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //获取全局唯一对象servletContext,在其中存放数据,key:字符串。value:对象
        ServletContext context = this.getServletContext();
        String name = "张三";
        context.setAttribute("name",name);

    }

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

获取数据的servlet类

public class getServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //获取servletContext对象
        ServletContext context = this.getServletContext();
        //设置响应的内容格式和编码
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");

        //获取context对象中的内容,并将其写在页面上
        String name = (String) context.getAttribute("name");
        resp.getWriter().write("名字:"+name);
    }

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

web.xml配置映射文件

<servlet>
    <servlet-name>sets</servlet-name>
    <servlet-class>com.rm.servlet.setServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>sets</servlet-name>
    <url-pattern>/sets</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>gets</servlet-name>
    <servlet-class>com.rm.servlet.getServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gets</servlet-name>
    <url-pattern>/gets</url-pattern>
  </servlet-mapping>

结果

在这里插入图片描述

5.5.2 获取初始化参数

配置初始化参数

<context-param>
  <param-name>url</param-name>
  <param-value>jdbc:mysql//localhost:3306/mybatis</param-value>
</context-param>

servlet类

public class servlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        //获取web.xml中配置的初始化参数
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }

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

结果

在这里插入图片描述

5.5.3 请求转发

  • 转发的时候地址栏路径不会发生变化,只是请求的页面变化了。

在这里插入图片描述

servlet类

public class servlet03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
     throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        //获取转发路径,并转发,访问该servlet的映射路径时,得到的是/gets页面的内容
        context.getRequestDispatcher("/gets").forward(req,resp);

    }

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

web.xml配置

 <servlet>
    <servlet-name>s3</servlet-name>
    <servlet-class>com.rm.servlet.servlet03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>s3</servlet-name>
    <url-pattern>/s3</url-pattern>
  </servlet-mapping>

结果
在这里插入图片描述

5.5.4 读取资源文件

  • 在java目录下新建properties

  • 在resources目录下新建properties

  • 发现都被打包到了同一个路径下,classes,通常把这个路径称为classpath。

  • 如果在java目录下新建的properties文件无法被maven打包,那么需要在pom.xml中配置。

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.properties</exclude>
                <exclude>**/*.xml</exclude>
            </excludes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

properties文件

username=zhangsan
password=123456

servlet类

public class servlet04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        //获取流对象/代表当前项目
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
        //创建properties对象,加载流获取数据
        Properties properties = new Properties();
        properties.load(is);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        //显示到页面上,设置内容和编码
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("username:"+username);
        resp.getWriter().print("password:"+password);

    }

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

web.xml配置

  <servlet>
    <servlet-name>s4</servlet-name>
    <servlet-class>com.rm.servlet.servlet04</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>s4</servlet-name>
    <url-pattern>/s4</url-pattern>
  </servlet-mapping>

结果
在这里插入图片描述

5.6 HttpServletResponse对象

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

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

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

public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;

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

public void setCharacterEncoding(String charset);
public void setContentLength(int len);
public void setContentLengthLong(long len);
public void setContentType(String type);
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public void setHeader(String name, String value);
public void addDateHeader(String name, long date);
public void setHeader(String name, String value);
public void addHeader(String name, String value);

5.6.1 下载文件

  • 向浏览器输出消息
  • 下载文件
    • 要获取下载文件的路径
    • 如何通过路径获取需要下载的文件名
    • 设置响应头Content-disposition
    • 获取下载文件的输入流
    • 创建缓冲区
    • 获取OutputStream对象
    • 将FileOutputStream流写入到buffer缓冲区
    • 使用OutputStream将缓冲区中的数据写到客户端。
public class servlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //   - 要获取下载文件的路径
        String file = "C:\\Users\\17312\\Pictures\\summer.jpg";
        //  - 如何通过路径获取需要下载的文件名
        String filename =file.substring(file.lastIndexOf("\\")+1);
        //  - 设置响应头Content-disposition
        resp.setHeader("Content-disposition", "attachment;filename=" + 
        URLEncoder.encode(filename,"utf-8"));
        
        //  - 获取下载文件的输入流
        FileInputStream fis = new FileInputStream(file);
        //  - 创建缓冲区
        int len =0;
        byte[] buffer = new byte[1024];
        //  - 获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
        //  - 将FileOutputStream流写入到buffer缓冲区
        while((len=fis.read(buffer))!=-1){
            //  - 使用OutputStream将缓冲区中的数据写到客户端。
            os.write(buffer,0,len);
        }
        os.close();
        fis.close();
    }

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

面试题:转发和重定向区别
相同点:

  • 页面都会实现跳转

不同点:

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

5.7 HttpServletRequest对象

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

获取前端传递的参数以及请求转发

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

        //设置请求编码和响应编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        //根据name属性获取表单提交的数据
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //复选框使用该方法返回多个值
        String[] hobbys = req.getParameterValues("hobbys");

        System.out.println("username:"+username);
        System.out.println("password:"+password);
        System.out.println(Arrays.toString(hobbys));

        //使用request对象进行重定向,不需要加虚拟路径
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

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

5.8 Cookie和Session

5.8.1 什么是会话

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

有状态会话:

  • 一个用户访问过该网站,下次再来的时候,我们会知道这个用户曾经来过这里。称之为有状态会话。

字符串编码和解码

//解码
URLDecoder.decode("你好","utf-8");
//编码
URLEncoder.encode("你好","utf-8");

5.8.2 Cookie

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

常见应用:网站登录之后,下次不用再登录了,第二次可以直接访问。

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

cookie一般会保存在本地的用户目录下,APPdata

public class Cookie1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
        //先设置浏览器请求和响应的编码
         req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        //判断此次访问是否携带有timeCookie,如果没有,显示第一次访问,如果有,显示欢迎回来,您上次访问时间是:
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){
            //说明存在cookie,不是头一次访问,获取cookie
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //看是否有timeCookie存在
                if("timeCookie".equals(cookie.getName())){
                    //将上次访问时间输出到页面
                    //将字符串形式的时间戳先转换为long类型,再转换为date类型
                    Long l = Long.parseLong(cookie.getValue());
                    Date date = new Date(l);
                    out.print("您上次访问的时间是:"+date.toLocaleString());
                }
            }
        }else {
            //不存在cookie,证明首次访问
            out.print("您好,欢迎首次访问");
        }

        //首次访问,将timeCookie交给客户端,值用时间戳表示
        Cookie cookie = new Cookie("timeCookie",System.currentTimeMillis()+"");
        //给cookie设置有效期,以秒为单位
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

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

5.8.3 Session(重点)

什么是Session:

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

Session和Cookie的区别

  • cookie是浏览器保存
  • session是服务器保存,session对象由服务器创建

使用场景:

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

得到session,并存放数据

public class Session1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //先设置请求和响应的编码,浏览器解析编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到请求里面的SessionID并将其输出到界面上
        HttpSession session = req.getSession();
        String id = session.getId();
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID: "+id);
        }else {
            resp.getWriter().write("Session已经存在服务器,ID:"+id);
        }

        //在Session中存入数据
        Person p = new Person("小明",25);
        session.setAttribute("name",p);

    }

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

在另一个页面获取session数据

public class Session2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //先设置请求和响应的编码,浏览器解析编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到Session对象,并取出数据
        HttpSession session = req.getSession();
        Person p = (Person) session.getAttribute("name");
        resp.getWriter().write(p.toString());
    }

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

session手动注销和设置默认生效时间

public class Session3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
        //先设置请求和响应的编码,浏览器解析编码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //得到Session对象,删除Session数据
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //将该session注销,手动注销
        session.invalidate();

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

设置默认注销时间

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

5.9 Filter过滤器

  • 用来过滤网站的数据
  • 用来处理乱码
public class FilterDemo1 implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

    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");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {
        System.out.println("服务器关闭,退出过滤器");

    }
}

xml中设置需要过滤的页面

    <servlet>
        <servlet-name>s1</servlet-name>
        <servlet-class>com.rm.servlet.Servlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>s1</servlet-name>
        <url-pattern>/servlet/s1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>s1</servlet-name>
        <url-pattern>/s1</url-pattern>
    </servlet-mapping>

    <!--配置过滤内容虚拟目录/servlet下的所有文件会被过滤,/s1不会被过滤-->
    <filter>
        <filter-name>f1</filter-name>
        <filter-class>com.rm.filter.FilterDemo1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>f1</filter-name>
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

5.10 监听器

  • 实现监听器的接口,重写方法
  • 在web.xml中注册监听器

统计网站在线人数

  • 存在一个session即有一个用户在线
public class listener1 implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        //Session被创建的时候执行
        HttpSession session = httpSessionEvent.getSession();
        ServletContext context = session.getServletContext();
        Integer Onlinecount = (Integer) context.getAttribute("count");

        //在context中存数据
        if(Onlinecount==null){
            //证明没有用户访问
            Onlinecount= new Integer(1);
        }else {
            int count = Onlinecount.intValue();
            Onlinecount = new Integer(count+1);
        }

        context.setAttribute("count",Onlinecount);

    }

    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

        //Session被销毁的时候执行
        HttpSession session = httpSessionEvent.getSession();
        session.invalidate();//手动销毁
        ServletContext context = session.getServletContext();
        Integer Onlinecount = (Integer) context.getAttribute("count");

        //在context中存数据
        if(Onlinecount==null){
            //证明没有用户访问
            Onlinecount= new Integer(0);
        }else {
            int count = Onlinecount.intValue();
            Onlinecount = new Integer(count-1);
        }

        context.setAttribute("count",Onlinecount);
    }
}
  • 销毁session
  • 手动销毁,设置session有效时间
   <!--配置监听器-->
    <listener>
        <listener-class>com.rm.listener.listener1</listener-class>
    </listener>
    <!--设置session有效时间-->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

5.11 过滤器常见应用

用户登录之后才能跳转到成功页面,用户注销后不能再通过url进入该页面了。

  • 用户登录之后,向session中放入用户的数据
  • 进入成功页面的时候要判断用户是否已经登录
//先将servletRequest强转为HttpServlet
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

//然后过滤掉没有SESSION_ID的请求
if (request.getSession().getAttribute(Constant.USER_SESSIONID)==null){
    response.sendRedirect("/failure.jsp");
}
filterChain.doFilter(servletRequest,servletResponse);

在这里插入图片描述
过滤器配置

<!--配置过滤器-->
<filter>
    <filter-name>loginFilter</filter-name>
    <filter-class>com.rm.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>loginFilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
</filter-mapping>

JSP

6.1什么是JSP

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

最大的特点:

  • 写JSP就像写HTML

区别:

  • HTML只能给用户提供静态的数据
  • JSP页面中可以嵌套JAVA代码,为用户提供动态数据

6.2 JSP原理

JSP本质还是Servle

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase

在这里插入图片描述
JSP内置了一些对象,可以直接使用

final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;

JSP将html标签自动生成了对应的JAVA代码
在JSP中编写的JAVA代码直接存在于Servlet中

out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");

6.3 JSP基础语法

  • 新建一个普通的mavne工程

导入项目依赖

    <dependencies>
        <!--servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!--jsp依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>
        <!--jstl表达式依赖-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--standard标签库-->
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>

    </dependencies>

添加项目框架支持

在这里插入图片描述

在这里插入图片描述
配置tomcat,deployment(部署)项目

6.3.1 JSP表达式

<%--jsp表达式,用于将java结果输出到客户端--%>
<%= new java.util.Date()%> 

6.3.2 JSP脚本片段

  <%--jsp脚本片段,java代码--%>
  <%
  int sum=0;
    for (int i = 1; i <= 100; i++) {
      sum +=i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
  %>

JSP脚本片段再实现,JSP代码中嵌套html代码

  <%--jsp脚本片段再实现--%>
  <%
    for (int i = 0; i < 3; i++) {
  %>
      <%= "Hello,World"+i%><br>
  <%
    }
  %>

在这里插入图片描述

  • 前面三种java代码都是在Servlet的service方法内部。
  • 如果想要定义全局变量,静态代码块或者是其他方法,则需要使用JSP声明

6.3.3 JSP声明

  • JSP声明:会被编译到JSP生成的Java类中,其他的会被生成到_jspService方法中

  • 在JSP页面中,嵌入JAVA代码即可

  • JSP的注释不会在客户端显示,HTML的会在客户端(查看源代码)显示。

  <%--JSP声明--%>
  <%!
    static {
      System.out.println("Servlet Loading...");
    }
    private String name;
    public void getName(String name){
        this.name =name;
    }
  %>

6.4 JSP指令

  • <%@ %>

  • 导包import

  • 定制错误界面errorPage

  • 提取网页公共部分

  • 本质还是三个界面,而不是将页面里面的内容合并在一起(建议使用)

<jsp:include page="common/Header.jsp"/>
<jsp:include page="common/Footer.jsp"/>
  • 本质是将页面里面的内容合并在一起,如果两个页面有相同命名的变量,则会跳转到500错误页面。(不建议使用)
 <%@include file="common/Header.jsp"%>
  <%@include file="common/Footer.jsp"%>

定制错误界面

  • 配置xml需要重启tomcat服务器
<error-page>
        <error-code>500</error-code>
        <location>/error/500.jsp</location>
 </error-page>

使用JSP指令配置

<%@ page errorPage="error/500.jsp" %>

6.5 JSP内置对象

  • PageContetx 存数据
  • Request [HttpServletRequest] 存数据
  • Response [HttpServletResponse]
  • Session [HttpSession] 存数据
  • Application [ServletContext] 存数据
  • config [ServletConfig]
  • out [JspWriter]
  • page
  • exception [Throwable]
作用域从小到大
PageContext(只在当前页面有效)
Request(一次请求有效,可以通过转发在其他Servlet中有效)
Session(一次会话有效,客户端浏览器关闭,设置的Session有效期到期后失效)
Application(服务器只要一直启动,数据就一直有效)

应用场景

  • request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻。
  • session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车商品。
  • application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可以继续使用,比如:聊天数据

6.6 JSP标签,JSTL标签,EL表达式

EL表达式:${}

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

JSTL表达式:

  • JSTL标签的使用是为了弥补HTML标签的不足,它自定义许多标签,标签的功能和Java代码一样。

核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

在这里插入图片描述

JSTL标签库使用步骤

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat服务器中也需要导入jstl的包,否则会报错,jstl解析错误

c:if

<form action="coreIf.jsp" method="post">
    <span>姓名:</span><input name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>
<%--判断如果username==admin,提示登录成功--%>
<c:if test="${param.username =='admin'}" var="isAdmin">
    <c:out value="管理员,欢迎您"/>
</c:if>
<c:out value="${isAdmin}"/>

c:foreach

<%
    //创建一个集合,并将其存放在当前页面中
    ArrayList<String> list = new ArrayList<>();
    list.add("张三");
    list.add("李四");
    list.add("王五");
    pageContext.setAttribute("peoples",list);
%>
<%--使用c标签foreach方法遍历集合--%>
<c:forEach var="people" items="${peoples}" begin="1" step="2">
    <c:out value="${people}"/><br/>
</c:forEach>

JDBC

7.1 什么是JDBC

Java连接数据库的原始方法

sql语句

CREATE DATABASE jdbc;
USE jdbc;

CREATE TABLE users(
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(20) NOT NULL,
	`password` VARCHAR(30) NOT NULL,
	email VARCHAR(20),
	birthday DATE

)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO users(`id`,`name`,`password`,`email`,`birthday`)
VALUES
(1,"张三",'123456','zs@qq.com','2000-01-01'),
(NULL,"李四",'123456','ls@qq.com','2000-01-01'),
(NULL,"王五",'123456','ww@qq.com','2000-01-01')

SELECT*FROM users;

导入数据库依赖

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

java代码

public class JDBC01 {
    public static void main(String[] args) throws Exception {
        //1.配置信息
        String url= "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="root";
        //2.加载驱动(通过反射)
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库连接对象,代表数据库。
        Connection connection = DriverManager.getConnection(url, username, password);
        //获取执行sql对象
        Statement statement = connection.createStatement();
        //编写sql语句
        String sql ="select*from users";
        //获得处理后的结果
        ResultSet rs = statement.executeQuery(sql);

        //使用迭代器遍历结果集
        while (rs.next()){
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("password="+rs.getObject("password"));
            System.out.println("email="+rs.getObject("email"));
            System.out.println("birthday="+rs.getObject("birthday"));
            System.out.println("==============");
        }
        //关闭连接,释放资源
        rs.close();
        statement.close();
        connection.close();
    }
}

7.2 JDBC步骤

  1. 加载驱动
  2. 连接数据库
  3. 向数据库发送SQL的对象statement:CRUD
  4. 编写sql(不同业务,不同sql)
  5. 执行sql,获取查询结果集或者受影响行数
  6. 关闭连接

预编译SQL

public class JDBC02 {
    public static void main(String[] args) throws Exception{
        //预编译处理sql,防止sql注入问题
        //1.配置信息
        String url= "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="root";
        //2.加载驱动(通过反射)
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库连接对象,代表数据库。
        Connection connection = DriverManager.getConnection(url, username, password);
        //4.编写sql
        String sql = "insert into users (id, name, password, email, birthday)values (?,?,?,?,?);";

        //获取执行sql预编译对象
        PreparedStatement statement = connection.prepareStatement(sql);

        //为?赋值
        statement.setInt(1,5);
        statement.setString(2,"赵六");
        statement.setString(3,"123456");
        statement.setString(4,"zl@qq.com");
        statement.setDate(5,new Date(new java.util.Date().getTime()));

        //执行sql
        int i = statement.executeUpdate();
        if(i>0){
            System.out.println("插入成功");
        }

        //关闭连接,释放资源
        statement.close();
        connection.close();
    }
}

7.3 事务

ACID原则

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

模拟事务

–建表–

CREATE TABLE account(
	id INT AUTO_INCREMENT PRIMARY KEY,
	`name` VARCHAR(20),
	`money` FLOAT(30)

)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO account(`name`,`money`)VALUES
('A',1000),
('B',1000),
('C',1000)

SELECT*FROM account;

Java代码

public class JDBC03 {
    public static void main(String[] args) {
        //模拟事务
        //1.配置信息
        String url= "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="root";
        Connection connection=null;
        PreparedStatement prep1=null;
        PreparedStatement prep2=null;
        try {
            //2.加载驱动(通过反射)
            Class.forName("com.mysql.jdbc.Driver");
            //3.获取数据库连接对象,代表数据库。
            connection = DriverManager.getConnection(url, username, password);
            //4.开启事务
            connection.setAutoCommit(false);
            //5.编写sql
            String sql1 ="update account set money =money-100 where name='A'";
            String sql2 ="update account set money =money+100 where name='B'";
            //6.获取预编译sql对象
            prep1 = connection.prepareStatement(sql1);
            prep2 = connection.prepareStatement(sql2);
            //7.执行sql
            prep1.executeUpdate();
            prep2.executeUpdate();
            //8.提交事务
            connection.commit();
            //9.将设置自动提交改回来
            connection.setAutoCommit(true);

        } catch (Exception e) {
            //无论出现什么异常,数据回滚
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            System.out.println("数据异常,事务回滚");

        } finally {
            try {
                if(connection!=null){
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if(prep1 !=null){
                    prep1.close();
                }
                if(prep2!=null){
                    prep2.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaWeb demo 是一个简单的 JavaWeb 应用程序示例。它主要用于展示如何创建一个简单的动态网站,并介绍了一些常用的 JavaWeb 技术。 这个 demo 可能包含以下几个方面的内容: 1. 前端页面:demo 可能包含多个静态 HTML 页面,通过 CSS 和 JavaScript 来实现页面的样式和交互效果。这些页面可能包含表单、按钮、导航栏等常见的网页组件。 2. 后端处理:demo 可能使用 Java Servlet 来处理前端页面的请求。Servlet 是 JavaWeb 开发中的一种常用技术,通过它可以接收和处理 HTTP 请求,并生成对应的响应。在 demo 中,Servlet 可能会读取表单数据、调用业务逻辑处理模块,并将处理结果返回给前端页面。 3. 数据库连接:demo 可能会使用 Java 中的数据库连接技术,如 JDBC,来与后端数据库进行交互。通过 JDBC,demo 可能会连接到数据库、执行 SQL 查询和更新操作,以及处理数据库返回的结果。 4. 业务逻辑:demo 可能会展示一些简单的业务逻辑,如用户注册、登录等。在这些功能中,demo 可能会将用户的输入数据存储到数据库中,或者验证用户的登录信息。 通过这个示例,开发者可以了解到如何搭建一个简单的 JavaWeb 应用程序,并了解到如何使用常见的 JavaWeb 技术来实现各种功能。这个 demo 还可以作为 JavaWeb 开发的一个入门教程,帮助开发者迅速上手和理解如何构建一个简单的动态网站。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值