4.Javaweb基础入门

JavaWeb

Java Web

1. 基本概念

1.1 前言

web开发

  • web 网页 www.baidu.com
  • 静态web
    • html,css
    • 提供给所有人看的数据始终不会发生变化
  • 动态web
    • 淘宝 几乎是所有的网站
    • 提供给所有人看的数据始终会发生变化 每个人在不同的时间 不同的地点看到的信息各不相同!
    • 技术栈: servlet/ISP 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这些都是网页的后缀 如果服务器上一直存在这些东西 我们就可以直接进行读取

4.Javaweb基础入门_第1张图片

  • 静态web存在的缺点
    • web页面无法动态更新 所有用户看到的都是同一个页面
      • 轮播图 点击特效 伪动态
      • JavaScript[实际开发中 用的非常多]
      • VBScript
    • 它无法和数据库交互(数据无法持久化 用户无法交互)

1.4 动态web

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

4.Javaweb基础入门_第2张图片

动态web的缺点

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

动态web的优点

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

    • 轮播图 点击特效 伪动态
    • JavaScript[实际开发中 用的非常多]
    • VBScript
  • 它可以和数据库交互(数据持久化 注册 商品买卖 用户交互…)

4.Javaweb基础入门_第3张图片

2 web服务器

2.1 技术讲解

ASP

  • 微软国内最早流行的就是ASP

  • 在HTML中嵌入了VB的脚本 ASP+COM

  • 在ASP开发中 基本一个页面(基本一个页面都有几千行的业务代码 页面机器混乱)

    <h1>
        <%
           System.out.println("你好")
           %>
        <h1>
    
  • 维护成本太高

  • C#

  • IIS

PHP

  • PHP开发速度很快 功能很强大 跨平台 代码很简单
  • 无法承载巨大的访问量(局限性) 但是大部分的网站都是中小型

JSP /Servlet

B/S 浏览器和服务器

C/S 客户端和服务器

  • sun公司主推的B/S架构
  • 基于Java语言(所有的大公司 和一些开元的组件 都是Java写的)
  • 可以承载三高问题(高性能 高并发 高性能)
  • 语法类似ASP ASP–>JSP 加强市场强度

2.2 web服务器

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

IIS

微软的ASP windows中自带的

Tomcat

Tomcat是Apache 软件基金会的Jakarta 项目中的一个核心项目,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,,成为目前比较流行的Web 应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,目前Tomcat最新版本为9.0.37**。**

下载Tomcat

  1. 安装 or 解压
  2. 了解配置文件及目录结构
  3. 这个东西的作用

3. Tomcat

3.1 安装Tomcat

Tomcat官方:https://tomcat.apache.org/

4.Javaweb基础入门_第4张图片

3.2 Tomcat

文件夹文件说明

4.Javaweb基础入门_第5张图片

启动 关闭Tomcat

4.Javaweb基础入门_第6张图片

访问测试http://localhost:8080/

可能遇到的问题

  1. Java环境变量没有配置
  2. 闪退问题需要配置兼容性
  3. 乱码问题 配置文件中的设置
    4.Javaweb基础入门_第7张图片

3.3 Tomcat配置

可以配置启动的端口号

可以配置主机的名称

  • Tomcat默认端口 8080

  • mysql 3306

  • http 80

  • https 443

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

可以配置主机的名称

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

面试题

网站是如何进行访问的

  1. 输入一个域名

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

    1. 有 返回对应的ip地址

      127.0.0.1 www.localhost.com
      
    2. 没有去DNS找 找到的话就返回 找不到就返回找不到

4.Javaweb基础入门_第8张图片

3.4 发布一个web网站

不会就先模仿

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

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

4 HTTP

4.1 什么是HTTP

HTTP

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

  • 文本 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://www.baidu.com/  请求地址
Request Method: GET    //get方法 post方法
Status Code: 200 OK		//状态码
Remote(远程) Address: 163.177.151.110:443   

1.请求行(general)

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

2 消息头(response)

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

4.4 HTTP响应

  • 服务器—响应—客服端

百度:

Cache-Control: private  //缓冲控制
Connection: keep-alive	//连接
Content-Encoding: gzip	
charset=utf-8 //编码
Content-Type: text/html; //类型
Accept: text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9   //语言
Cache-Control: max-age=0
Connection: keep-alive

1. 响应体(request)

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

2.响应状态码

200:请求响应成功

3**:请求重定向

  • 重定向:重新到我给你的新位置上去

4**:找不到资源

  • 资源不存在 404

5**:服务器代码错误 500 502网关错误

常见面试题

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

5 Maven

为什么要学习这个技术

  1. 在javaweb开发中 需要使用大量的jar包 我们要手动导入
  2. 如何能够让一个东西自动帮我导入这个和配置这个jar包

由此Maven诞生了

5.1 Maven架构管理工具

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

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

  • 有约束 不要去违反

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

5.2 下载安装Maven

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

4.Javaweb基础入门_第9张图片

下载完解压即可:

电脑的所有环境最好放一起

4.Javaweb基础入门_第10张图片

5.3 配置环境变量

在我们的系统环境变量中

配置如下

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录
  • 在系统的path中配置 %MAVEN_HOME%\bin

4.Javaweb基础入门_第11张图片

测试是否成功

4.Javaweb基础入门_第12张图片

5.4 阿里云镜像

  • mirrors
    • 作用 加速我们的下载
  • 国内建议使用阿里云的镜像
    • https://developer.aliyun.com/article/512821
      4.Javaweb基础入门_第13张图片

5.5 本地仓库

在本地的仓库 远程仓库

建立一个本地仓库 (新建文件夹 maven-repo)

4.Javaweb基础入门_第14张图片

4.Javaweb基础入门_第15张图片

5.6 在IDEA中使用Maven

  1. 启动IDEA

  2. 4.Javaweb基础入门_第16张图片

  3. 4.Javaweb基础入门_第17张图片

  4. 4.Javaweb基础入门_第18张图片

  5. 等待项目初始化

6.4.Javaweb基础入门_第19张图片

  1. IDEA中的Maven设置

4.Javaweb基础入门_第20张图片

  1. 到这里 Maven就已经配置完成了

5.7 创建一个普通的Maven项目

不选择要导入的maven包 直接创建一个普通的Maven项目

4.Javaweb基础入门_第21张图片

选择了javaweb的项目 这个只有在Web应用下才有

4.Javaweb基础入门_第22张图片

5.8 标记文件夹功能

4.Javaweb基础入门_第23张图片

4.Javaweb基础入门_第24张图片

5.9 在IDEA中配置Tomcat

4.Javaweb基础入门_第25张图片

4.Javaweb基础入门_第26张图片

4.Javaweb基础入门_第27张图片

5.10 pom文件

pom.xml是Maven的核心配置文件

4.Javaweb基础入门_第28张图片



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

  <groupId>com.lhcgroupId>
  <artifactId>javaweb-01-mavenartifactId>
  <version>1.0-SNAPSHOTversion>

  <packaging>warpackaging>

  <name>javaweb-01-maven Maven Webappname>
  
  <url>http://www.example.comurl>

  <properties>

    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

    <maven.compiler.source>1.8maven.compiler.source>
    <maven.compiler.target>1.8maven.compiler.target>
  properties>

  <dependencies>

    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.11version>
      <scope>testscope>
    dependency>
  dependencies>

  <build>
    <finalName>javaweb-01-mavenfinalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-pluginartifactId>
          <version>3.1.0version>
        plugin>
        
        <plugin>
          <artifactId>maven-resources-pluginartifactId>
          <version>3.0.2version>
        plugin>
        <plugin>
          <artifactId>maven-compiler-pluginartifactId>
          <version>3.8.0version>
        plugin>
        <plugin>
          <artifactId>maven-surefire-pluginartifactId>
          <version>2.22.1version>
        plugin>
        <plugin>
          <artifactId>maven-war-pluginartifactId>
          <version>3.2.2version>
        plugin>
        <plugin>
          <artifactId>maven-install-pluginartifactId>
          <version>2.5.2version>
        plugin>
        <plugin>
          <artifactId>maven-deploy-pluginartifactId>
          <version>2.8.2version>
        plugin>
      plugins>
    pluginManagement>
  build>
project>

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


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

5.11 IDEA操作

Maven中jar包的联系的关联图

4.Javaweb基础入门_第29张图片

5.12 遇到的问题

1.Maven3.6.2

解决方法 降级为3.6.1

2.Tomcat闪退

配置Tomcat start.bat文件(目前不知道怎么解决)

3.IDEA每次都要重复配置Maven

在IDEA中全局默认配置中去配置

4.Javaweb基础入门_第30张图片

4.Javaweb基础入门_第31张图片

4.maven默认web项目中的web.xml版本问题

4.Javaweb基础入门_第32张图片

替换为wenbapp4.0版本和Tomcat一致


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

  <display-name>Welcome to Tomcatdisplay-name>
  <description>
    Welcome to Tomcat
  description>

web-app>

5.Maven项目中无法配置Tomcat

必须要的配置 :为什么会有这个问题 我们访问一个网站 需要制定一个文件夹名字

切记 下面的配置文件是你现在的项目 不是其他的

还有 一定要打开Tomcat服务 不然怎么调整也没用

还有 一定要打开Tomcat服务 不然怎么调整也没用

还有 一定要打开Tomcat服务 不然怎么调整也没用

4.Javaweb基础入门_第33张图片

1.4.Javaweb基础入门_第34张图片

  1. 4.Javaweb基础入门_第35张图片

  2. 4.Javaweb基础入门_第36张图片

6.maven仓库的使用

进入官方https://mvnrepository.com/?cf_chl_captcha_tk=a48f18039660094440761e1b6d230ce6a69c55f8-1602326539-0-Afkz8Ted5KWfCo94r18BZ1Np84NIY65dJzT-JICrG8uKuvDHc7d-Vj3KkCSmvqWeivkNh-6pDMkZlW4_GZfollylgMnsz4bsA3sgmXHNuQRa89eW_4iPugscHbCD8MSdAKmS1zgUmaL5HGqMV3I0z3LK351OLOdCVvPbVQ57dGc-17W1Mg-TUEiVQS0hL5JfJi1GioiVogtA28MlXOmYAJAeGAw6_Mbew9qG38W2yGGQZ45voy_d1toUH8IgPY3h-87F-vB378PXe_xno313C-M4asXkOYRzKzn3F6pnmX8cqvQUaCqF1hLgvTocE4Q9V2AtDiXRS5Yd1pTeKOt0iXNsA1Af-5Yt3dxIBi9Mpr8CFTgcPZB–rCU7mdxI7iEq22JYDL8KU_bPEBddTMDztzk6vWvB8bKTLsVbmxb-6yvxT2sIxru83u6Y2oqpvIasLeyAz5p2z5KiwkVDRgg8V900O-OXi2MTwy1h3XXZLCcvguicxaSYruWdBepEITZNXOA_fXDA6R2dPNsnIz8myRet7ZfGvu8o5IYEiL-y64v

在这里插入图片描述
4.Javaweb基础入门_第37张图片

6.Servlet

6.1 Servlet简介

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

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

6.2 HelloServlet

Servlet接口有两个默认的实现类 HttpServlet,GenericServlet

  1. 构建一个普通Maven项目 删掉里面的src目录 以后我们的学习就在这个项目里面简历moudel 这个空的工程就是Maven的主工程

  2. guanyu Maven父子工程的理解:

    父项目中会有

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

    子项目中会有

    <parent>
        <artifactId>javaweb-02-servletartifactId>
        <groupId>com.lhcgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    

    父项目中的java子项目可以直接使用

    son extends father
    
  3. Maven环境优化

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

    1. 编写一个普通类

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

    3. 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 {
              doGet(req, resp);
          }
      }
      
  5. 编写Servlet的映射

    为什么需要映射 我们写的是java程序 但是要通过浏览器访问

    浏览器需要连接web服务器

    所以我们需要在web服务器中注册我们写的Servlet

    还需要给他一个浏览器能够访问的路径

    
    <servlet>
        <servlet-name>helloservlet-name>
        <servlet-class>com.lhc.servlet.HelloServletservlet-class>
    servlet>
    
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    
  6. 配置Tomcat

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

  7. 启动测试

6.3 Servlet原理

Servlet是由Web服务器调用

web服务器在收到浏览器请求之后 会:

4.Javaweb基础入门_第38张图片

6.4 Mapping问题

  1. 一个Servlet可以指定一个映射路径(http://localhost:8080/hello)

    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    
  2. 一个Servlet可以指定多个映射路径(http://localhost:8080/s1/hello1 http://localhost:8080/s1/hello2 http://localhost:8080/s1/hello3 )

    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hello1url-pattern>
    servlet-mapping>
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hello2url-pattern>
    servlet-mapping>
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hello3url-pattern>
    servlet-mapping>
    
  3. 一个Servlet可以指定通用映射路径(比如访问http://localhost:8080/s1/qwjkejka)

    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hello/*url-pattern>
    servlet-mapping>
    
  4. 默认请求路径(怎么访问都是hello这个servlet)

    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/*url-pattern>
    servlet-mapping>
    
  5. 指定一些后缀或者前缀等等…(比如访问http://localhost:8080/s1/dsklajdlkaj.lhc http://localhost:8080/s1/hello1/dasdasjh.lhc )*前面不能写/ 但是只要是最后是.lhc就可以映射到

        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>*.lhcurl-pattern>
        servlet-mapping>
    
  6. 优先级问题

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

6.5 ServletContext

web容器在启动的时候,它会为每个web程序都创建一个的ServletContext对象 它代表了当前web应用;

1.共享数据

我在这个Servlet中保存的数据 可以在另外一个Servlet中拿到

设置要拿走的username数据的类

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getInitParameter()  初始化参数
        //this.getServletConfig()  Servlet配置
        //this.getServletContext();Servlet上下文
        ServletContext context = this.getServletContext();
        

        String username="林宏程";//数据
        context.setAttribute("username",username);//将一个数据保存在了ServletContext 名字为username 值为 林宏程
        
        System.out.println("hello");
    }
}

设置一个获取username数据的类

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");//配置content的传输格式
        resp.setCharacterEncoding("utf-8");//配置content的编码
        resp.getWriter().println("名字"+username);
    }

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

配置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">
    <servlet>
        <servlet-name>helloservlet-name>
        <servlet-class>com.lhc.servlet.HelloServletservlet-class>




    servlet>
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>

    <servlet>
        <servlet-name>getcservlet-name>
        <servlet-class>com.lhc.servlet.GetServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>getcservlet-name>
        <url-pattern>/getcurl-pattern>
    servlet-mapping>


web-app>

访问的结果 需要先访问/hello 再访问/getc才能获取到username

2.获取初始化参数


    <context-param>
        <param-name>urlparam-name>
        <param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
    context-param>
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();

        String url = context.getInitParameter("url");
        resp.getWriter().println(url);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.请求转发

public class ServletDemo04  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("进入了ServletDemo04");

        //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
        //requestDispatcher.forward(req,resp);//调用forward实现请求转发
        context.getRequestDispatcher("/gp").forward(req,resp);

    }
}

请求转发和重定向的区别

A B C是3个网站 A需要C的数据

请求转发过程

4.Javaweb基础入门_第39张图片

重定向

4.Javaweb基础入门_第40张图片

4.读取资源文件

Properties

  • 在java目录下新建Properties
  • 在resource目录下新建Properties

发现 都被打包了同一个目录下 classes 我们俗称为classpath(类路径)

但是放在java下的db.properties需要在pom.xml加入


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

思路 需要一个文件流

username=lhc
password=123456

然后用InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");获取里面的流

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");

    Properties prop1 = new Properties();
    prop1.load(is);
    String user1 = prop1.getProperty("username");
    String pwd1 = prop1.getProperty("password");

    resp.getWriter().println("lhc_username="+user1);
    resp.getWriter().println("lhc_password="+pwd1);


    InputStream si = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/lhc/servlet/aa.properties");

    Properties prop2 = new Properties();
    prop2.load(si);
    String user2 = prop2.getProperty("username");
    String pwd2 = prop2.getProperty("password");

    resp.getWriter().println("lt_username="+user2);
    resp.getWriter().println("lt_password="+pwd2);
}

访问测试即可

5.假如resource文件夹或者java文件夹打包失败

4.Javaweb基础入门_第41张图片

4.Javaweb基础入门_第42张图片

6.6HttpServletResponse

响应

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

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

1.简单的分类

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

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

响应的状态码

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2.常见应用

  1. 向浏览器输出消息(resp.getWriter().println(“lt_username=”)

  2. 下载文件

    1. 要获取下载文件的路径
    2. 下载的文件名叫什么
    3. 想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutputStream对象
    7. 将FileOutputStream流写入到buffer缓冲区
    8. 使用OutputStream将缓冲器中的数据输出到客户端

mapping不再说明

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1. 要获取下载文件的路径
    String realPath ="F:\\JAVA的学习\\6.JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\a.jgp";
    System.out.println("下载文件的路径"+realPath);

    //2. 下载的文件名叫什么
    String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);

    //3. 想办法让浏览器能够支持下载我们需要的东西 如果文件有中文 URLEncoder.encode()编码 否则有可能有乱码
    resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));

    //4. 获取下载文件的输入流
    FileInputStream in = new FileInputStream(realPath);

    //5. 创建缓冲区
    int len=0;
    byte[] buffer = new byte[1024];

    //6. 获取OutputStream对象
    ServletOutputStream out = resp.getOutputStream();

    //7. 将FileOutputStream流写入到buffer缓冲区
    while((len=in.read(buffer))>0){
        out.write(buffer,0,len);
    }
    in.close();
    out.close();
    //8. 使用OutputStream将缓冲器中的数据输出到客户端
}

3.验证码

验证码怎么来的?

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

mapping不再说明

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //如果让浏览器5S刷新一次
    resp.setHeader("refresh","3");

    //在内存中创建一个图片
    BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);

    //得到图片
    Graphics2D g = (Graphics2D)image.getGraphics();//相当于一个笔

    //设置图片的背景颜色
    g.setColor(Color.white);
    g.fillRect(0,0,80,20);

    //给图片写数据
    g.setColor(Color.blue);
    g.setFont(new Font(null,Font.BOLD,20));
    g.drawString(makeNum(),0,20);

    //告诉浏览器 这个请求用图片的方式打开
    resp.setContentType("image/jpg");

    //网站存在缓冲 不让浏览器缓冲
    resp.setDateHeader("expires",-1);
    resp.setHeader("Cache-Control","no-cache");
    resp.setHeader("Pragma","no-cache");

    //把图片写给浏览器
    ImageIO.write(image,"jpg",resp.getOutputStream());
}

//生成随机数
private String makeNum(){
    Random random = new Random();
    String num = random.nextInt(9999999) + "";
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 7 - num.length(); i++) {
        sb.append("0");
    }
    String s = sb.toString() + num;//保证num是7位 如果随机小于7位数就用0填充
    return num;
}

4.实现重定向

4.Javaweb基础入门_第43张图片

一个web资源受到客户端请求后 他会通知客户端去访问另外一个web资源 这个过程叫重定向

常见场景

  • 用户登入
void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        resp.setHeader("Location","/response_war/img");
    //        resp.setStatus(302);//重定向代码
    resp.sendRedirect("/response_war/img");//重定向
}

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

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候 url不会产生变化(输入目的就可以)
  • 重定向的时候 url地址栏会发生变化(输入绝对路径)

请求转发过程

4.Javaweb基础入门_第44张图片

重定向

4.Javaweb基础入门_第45张图片

模拟登入

RequestTest.java

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入了这个请求");
        //处理请求
        String username = req.getParameter("username");//获取前端发来的username
        String password = req.getParameter("password");//获取前端发来的password

        System.out.println(username+"====="+password);
        //重定向的时候 一定要注意路径问题(绝对网页路径) 否则404
        resp.sendRedirect("/r/success.jsp");
    }

index.jsp



Hello World!

<%--这里提交的路径 需要寻找到项目的路径--%> <%--${pageContext.request.contextPath()}代表当前的项目--%>
用户名 密码

success.jsp



    Title


成功登入

从这里可以得出一个理解:

后台和前端的连接就是servlet mapping来连接的 index.jsp里有一个${pageContext.request.contextPath}/login

${pageContext.request.contextPath}指定当前页面 /login是通过mapping映射的/login才找到了 RequestTest.java 然后再通过RequestTest.java 处理这个请求 用resp.sendRedirect("/r/success.jsp");重定向到success.jsp 而控制台里输出 {进入了这个请求 1025993689=====1} 也说明前端的内容已经被我们后端获取到了

6.7HttpServletRequest

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

4.Javaweb基础入门_第46张图片

4.Javaweb基础入门_第47张图片

1.获取前端传递的参数

4.Javaweb基础入门_第48张图片

2.请求转发

重定向和转发的区别

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候 url不会产生变化(输入目的就可以) 307
  • 重定向的时候 url地址栏会发生变化(输入绝对路径) 302

请求转发过程

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobbies");
        //后台接受中文乱码的问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        System.out.println(username);
        System.out.println(password);
        System.out.println(hobbies);


        //通过请求转发
        //说明 这里的/就代表当前的web引用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
        resp.setCharacterEncoding("utf-8");
    }
}

7.Cookie Session

7.1会话

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

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

如何证明自己是福建工程学院的学生?

你 福建工程学院

  1. 学生证 福建工程学院给你学生证
  2. 学校登记 福建工程学院标记你是这个学院的学生

一个网站 怎么证明你来过

客户端 服务器

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

7.2保存会话的两种技术

cookie

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

session

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

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

7.3cookie

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lfngq64z-1603629176227)(…/图片/image-20201017200941908.png)]

  1. 从请求中拿到cookie信息

  2. 服务器响应给客服端cookie

  3. Cookie[] cookies = req.getCookies();//获得cookie
    cookie.getName()//获得cookie中的key
    cookie.getValue()//获得cookie中的value
    Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
    cookie.setMaxAge(24*60*60);//设置cookie的有效期
    resp.addCookie//响应给客户端一个cookie
    
  4. cookie 一般会保存在本地的 用户目录下appdata;

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

  • 一个Cookie只能保存一个信息
  • 一个web沾点可以给浏览器发送多个cookie 每个站点最多存放20个cookie
  • cookie大小有限制 4KB
  • 浏览器上限是300个

删除cookie

  • 不设置有效期 关闭浏览器 自动失效
  • 设置有效期时间为0 可以直接删除cookie

编码解码

//解码 这个是解决cookie的乱码
out.write(URLDecoder.decode(cookie.getValue(), "UTF-8"));
//编码  这个是解决cookie的乱码
Cookie cookie = new Cookie("name", URLEncoder.encode("林宏程", "UTF-8"));

cookie的实际使用

保存用户上一次访问的时间

//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器 告诉你 你来的时间 把这个时间封装成一个 信件 你下次带来 我就知道你来了

        //解决中文乱码 chrome要编码改成GBK才能解决乱码
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");

        PrintWriter out = resp.getWriter();
        //cookie 服务器端从客户端获取
        Cookie[] cookies = req.getCookies();//这里返回数组 说明cookie可能存在多个 这里是第一次创建 所以获得的cookie肯定是空的 在第二次执行的时候会把新建的cookie赋值给这个cookies

        //判断 cookie是否存在
        if (cookies!=null){

            //如果存在怎么办?
            out.write("你上一次访问的时间是:");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("lastLoginTime")){
                    //获取cookie中的值

                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }

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

        //服务器给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
        
        //有效期为24*60*60秒 为1天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

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

删除cookie

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //创建一个cookie 名字必须要和删除的名字一致
    Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");

    //将cookie有效期设为0 立马过去
    cookie.setMaxAge(0);

    resp.addCookie(cookie);

}

解决中文传值乱码问题(解码编码)

//中文数据传递
public class CookieDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");

        Cookie[] cookies = req.getCookies();
        PrintWriter out = resp.getWriter();

        if (cookies != null) {

            //如果存在怎么办?
            out.write("你的名字:");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("name")) {
                    //获取cookie中的值
                    //解码 这个是解决cookie的乱码
                    out.write(URLDecoder.decode(cookie.getValue(), "UTF-8"));
                }

            }
        } else {
            out.write("这是你第一次访问本站");
        }
        //编码  这个是解决cookie的乱码
        Cookie cookie = new Cookie("name", URLEncoder.encode("林宏程", "UTF-8"));
        resp.addCookie(cookie);
    }

7.4Session(重点)

4.Javaweb基础入门_第49张图片

什么是Session?

  • 服务器会给每个客服端(浏览器)创建一个Session
  • 一个Session独占一个浏览器 只要浏览器没有关闭 这个Session就存在
  • 用户登入之后 整个网站他都可以访问 -->保存用户的信息 保存购物车的信息

常用的一些方法

4.Javaweb基础入门_第50张图片

Session和Cookie的区别

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

区别小总结:Session像是一个储藏柜 客户端需要SessionID才能拿到储藏柜里的资源 Cookie是直接把储藏柜里的资源让客户端拿走 下次来的时候直接使用这个资源

使用场景:

  • 保存一个登入用户的信息
  • 购物车信息
  • 在整个网站中 经常会使用的数据 我们将他保存在Session中

使用Session

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

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

        //给Session中存东西
        session.setAttribute("name",new Person("林宏程",24));

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

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

        //Session创建的时候做了什么事情
//        Cookie cookie = new Cookie("JSESSIONID", "71804CF271369B39C1BF1EC0280BDE16");
//        resp.addCookie(cookie);


    }

调用Session

person对象

public class Person {
    private String name;
    private int age;
}

使用(创建Session在上面的 Session使用)

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

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

    Person person = (Person)session.getAttribute("name");

    System.out.println(person.toString());

}

注销Session

手动注销

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();

    session.removeAttribute("name");

    //手动注销session
    session.invalidate();
}

设置有效期(在web.xml)


    <session-config>

        <session-timeout>15session-timeout>
    session-config>

思考 假如你用两个浏览器去访问这些网站 但是你是需要的资源是同样的

4.Javaweb基础入门_第51张图片

8 JSP

需要的导入包

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


dependencies>

8.1什么是JSP

JSP已经过时 这里的内容只需要了解 理解代码即可

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

最大的特点

  • 写JSP就像在写HTML
  • 区别
    • HTML只给用户提供静态的数据
    • JSP页面中嵌入Java代码 为用户提供动态数据

8.2 JSP原理

JSP到底怎么执行的?

  • 代码层面没有任何问题

  • 服务器内部工作

    Tomcat中有一个work目录

    IDEA中使用Tomcat的会在IDEA中Tomcat中产生一个work目录

4.Javaweb基础入门_第52张图片

在这里插入图片描述

页面转变成了Java程序

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

JSP最终也会转换成一个Java类!

JSP本质就是个Servlet

//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSP Service
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
    throws java.io.IOException, javax.servlet.ServletException
  1. 判断请求

  2. 内置了一些对象

    final javax.servlet.jsp.PageContext pageContext; //页面上下文
    final javax.servlet.ServletContext application;//applicationcontext
    final javax.servlet.ServletConfig config;		//conig
    javax.servlet.jsp.JspWriter out = null;			//out
    final java.lang.Object page = this;				//page
    HttpServletRequest request						//请求
    http.HttpServletResponse						//响应
    
  3. 输出页面前增加的代码

    response.setContentType("text/html; charset=UTF-8");//这是响应的页面类型
    pageContext = _jspxFactory.getPageContext(this, request, response,
                                              null, false, 8192, true);
    _jspx_page_context = pageContext;
    application = pageContext.getServletContext();
    config = pageContext.getServletConfig();
    out = pageContext.getOut();
    _jspx_out = out;
    
  4. 以上的这些个对象我们可以在JSP页面中直接使用

4.Javaweb基础入门_第53张图片

在JSP页面中 只要是Java代码 就会原封不动的输出

如果是HTML代码 就会转换成:

out.write("/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("

sum="+sum+"

"); %>

脚本片段的再实现

<%--在代码中嵌入HTML元素--%>
<%
    for (int i = 0; i < 5; i++) {
%>
    

你好!<%=i %>

<% } %>

JSP声明

<%!
    static {
        System.out.println("Loading Servlet");
    }
    
    private int globalVar=0;

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

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

在JSP 嵌入Java即可

<%%>
<%=%>
<%!%>
<%--注释--%>


<%--JSP的注释--%>

JSP的注释不会在客服端显示 HTML会

8.4 JSP指令

4.Javaweb基础入门_第54张图片

jsp3

<%@ page args... %>
<%@ include File %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>



    Title



<%-- <%@ include %>会将两个页面合二为一 直接把代码写到_jsp.java中 --%>
<%@ include file="common/header.jsp" %>

我是主体

<% int i=10;//因为他是直接用put.write输出 所以在这个页面不会报错 在web执行的时候 才会调用 那个时候才会报错 所以用下面的更加好 %> <%@ include file="common/footer.jsp" %>
<%-- 拼接页面 在静态方法中调用这2个页面 --%> <%--JSP标签 这里的路径是web--%>

我是主体

<% int i=10;//因为这个实现是直接调用本类静态方法 所以他会直接报错(i 已经定义) %>

header

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

我是header

footer

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

我是footer

<% int i=10; %>

实际页面(没有测试 变量i调用的问题)

4.Javaweb基础入门_第55张图片

8.5 九大内置对象

pageContext 存东西
Request 存东西
Response
Session 存东西
Application(ServletContext) 存东西
config(ServletConfig)
out
page 几乎不用
exception

4个内置对象的作用域

生成各自Attribute

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

//这里做了个小测试 如果用请求转发(pageContext.forward)到 pageDemo02.jsp request还是可以读取到的 但是如果用重定向(response.sendRedirect)这里的request就读取不到了
response.sendRedirect("pageDemo02.jsp");
pageContext.forward("pageDemo02.jsp");

//在重定向中 A到C的时候没有转发只有请求 所以丢失了request的数据了
//而请求转发中 他是A请求B B转发C C请求B B转发A (这个理解不知道是不是对的)

转到第二个页面后去查找

<%

    //通过pageContext取出 我们通过寻找的方式来找
    //从底层到高层(作用域) page-->request-->session-->application
    //JVM 双亲委派机制:一个类使用方法找不到的时候 会不断向父类去找有没有存在这个方法 如果找不到就报异常 如果和根类名字一样会被无视 (听着高大上 其实很简单
    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");//不存在
%>

<%--使用EL表达式--%>
<h1>取出的值为</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>

<%-- EL表达式会自动过滤不存在的 但是这个不会--%>
<h3><%=name5%></h3>

原理图

请求转发过程

4.Javaweb基础入门_第56张图片

重定向

4.Javaweb基础入门_第57张图片

4.Javaweb基础入门_第58张图片

更改作用域

//可以设置他的作用域
pageContext.setAttribute("hello","hello",pageContext.SESSION_SCOPE);
//session.setAttribute("hello","hello"); 等价上面的代码

总结

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

  • session 客户端向服务器发送请求 产生的数据 用户用完 一会还有用 比如 购物车

  • application 客户端向服务器发送请求 产生的数据 用户用完 其他用户还可能使用 比如 QQ聊天数据

8.6 JSP标签 JSTL标签 EL表达式

EL表达式

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

JSP标签

设值

jsptag1

<%--

取值

jsptag2


<%--取出参数--%> name: <%=request.getParameter("name")%>
age: <%=request.getParameter("age")%>

JSTL表达式

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

格式化标签

SQL标签

XML标签

核心标签(部分掌握)

4.Javaweb基础入门_第59张图片

JSTL标签库使用步骤

  • 引入对应的taglib

    <%--引入JSTL核心表艰苦 我们才能使用JSTL标签--%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  • 使用其中的方法

  • 在Tomcat的lib包也需要引入JSTL的包 否则会报错 JSTL解析错误

IF使用

if测试


<%-- EL表达式获取表单中的数据 ${param.参数名} --%>
<%--判断如果提交的用户名管理员 则登入成功--%> <%--<%--%> <%-- if(request.getParameter("username").equals("admin")){--%> <%-- out.print("登入成功");--%> <%-- }--%> <%--%>--%>

4.Javaweb基础入门_第60张图片

when使用
<%--定义一个变量score 值为85--%>



    
        你的成绩为优秀
    

    
        你的成绩为一般
    


在这里插入图片描述

foreach使用
<%
    ArrayList people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"赵六");

    request.setAttribute("list",people);

%>
<%--
var 每一次遍历出来的变量
item 要遍历的对象
begin  哪里开始
step    步长
end     哪里结束
--%>

     


4.Javaweb基础入门_第61张图片

这里只出来上面的遍历 下面的没出来

9 JavaBean

实体类

JavaBean有特定的写法

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

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

ORM 对象关系映射

  • 表—>类
  • 字段—>属性
  • 行记录—>对象

people表

id name age address
1 林宏程1 3 温州
2 林宏程2 4 温州
3 林宏程3 5 温州
class people{
	private int id;
    private String name;
    private int age;
    private String address;
}
class A{
    new people(1,"林宏程1",3,"温州")
    new people(2,"林宏程1",4,"温州")
    new people(3,"林宏程1",5,"温州")
}

10MVC三层架构

什么MVC:model view controller 模型/视图/控制器

10.1早些年开发

在这里插入图片描述

用户直接访问控制层 控制层就可以直接操作数据库

servlet--CRUD-->数据库
弊端 程序十分臃肿       
servlet的代码中 处理请求 响应 视图跳转 处理JDBC 处理业务代码 处理逻辑代码
    
架构 没有什么是加一层解决不了的
    
程序员调用
|
JDBC
|    
Mysql

10.2三层架构

4.Javaweb基础入门_第62张图片

Model

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

View

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

Controller

  • 接受用户的请求 (request.请求参数 Session信息…)

  • 交给业务层处理对应的代码

  • 控制跳转

    登入---->接受用户的登入请求---->处理用户的请求(获取用户登入的参数 username password)---->交给业务层处理登入业务(判断用户名密码是否正确:事务)---->Dao层查询用户层和密码是否正确---->数据库
    

11.Filter(重点)

这里的代码无法实现 目前无法解决这个bug 显示没有导入javax.servlet.Servlet 但是实际上导入了

Filter 过滤器 用来过滤网站的数据

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

4.Javaweb基础入门_第63张图片

Filter开发步骤

  1. 导包

  2. 编写过滤器(切记是这个包)

4.Javaweb基础入门_第64张图片

public class CharacterEncodingFilter implements Filter{
    //初始化 web服务器启动 就已经初始化了 随时等待过滤对象
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter 初始化");
    }

    //chain 链
    /*
    1.过滤中的所有代码 在过滤特定请求的时候回执行
    2.必须要让过滤器继续同行

     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");

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

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

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

    }

    //销毁 web服务器关闭的时候 过滤会销毁
    public void destroy() {
        System.out.println("CharacterEncodingFilter 销毁");

    }
}
  1. web.xml配置Filter过滤器(新的版本已经更改这样了 原来是用servlet来映射的)

        <filter>
            <filter-name>filterfilter-name>
            <filter-class>com.lhc.filter.filterfilter-class>
        filter>
        <filter-mapping>
            <filter-name>filterfilter-name>
            <url-pattern>/servlet/*url-pattern>
        filter-mapping>
    

12.监听器

实现个监听器的接口:

  1. 编写一个监听器

    public class OnlineCountListener implements HttpSessionListener {
        //创建session监听 看你的一举一动
        //一旦创建一个session 就会触发一次这个事件
        public void sessionCreated(HttpSessionEvent se) {
            ServletContext ctx = se.getSession().getServletContext();
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if(onlineCount==null){
                onlineCount=new Integer(1);
            }else {
                int count=onlineCount.intValue();
                onlineCount = new Integer(count++);
            }
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    
        //销毁session监听
        //一旦销毁一个session 就会触发一次这个事件
        public void sessionDestroyed(HttpSessionEvent se) {
            ServletContext ctx = se.getSession().getServletContext();
            Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
    
            if(onlineCount==null){
                onlineCount=new Integer(0);
            }else {
                int count=onlineCount.intValue();
                onlineCount = new Integer(count--);
            }
            ctx.setAttribute("OnlineCount",onlineCount);
        }
    
    }
    
  2. web.xml注册监听器

    
    <listener>
        <listener-class>com.lhc.listener.OnlineCountListenerlistener-class>
    listener>
    
  3. 看情况是否使用

13.过滤器 监听器常见应用

监听器 GUI编程中经常使用

package com.lhc.listener;

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("你好!");//新建一个窗体
        Panel panel = new Panel(null);//面板
        frame.setLayout(null);//设置窗体的布局


        frame.setBounds(300, 300, 500, 500);
        frame.setBackground(new Color(0, 0, 255));//设置背景颜色

        panel.setBounds(50, 50, 300, 300);
        frame.setBackground(new Color(0, 255, 0));//设置背景颜色

        frame.add(panel);

        frame.setVisible(true);

        //监听事件
        frame.addWindowListener(new WindowListener() {
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");

            }

            public void windowClosing(WindowEvent e) {
                System.out.println("关闭中");
                System.exit(0);
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("关闭");
            }

            public void windowIconified(WindowEvent e) {

            }

            public void windowDeiconified(WindowEvent e) {

            }

            public void windowActivated(WindowEvent e) {

            }

            public void windowDeactivated(WindowEvent e) {

            }
        });

    }
}

需求:用户登入之后才能进入主页 用户注销后就不能进入主页

  1. 用户登入的时候给用户一个session(session是存在服务器里的 每个用户都能获得自己的session )

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端请求的参数
    
        String username = req.getParameter("username");
    
        if(username.equals("admin")){
            //登入成功
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect("/sys/success.jsp");
        }else {
            //登入失败
            resp.sendRedirect("error.jsp");
        }
    
    
    }
    
  2. 注销的时候要清除用户session

    
    

    错误

    没有权限 用户名错误
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute("USER_SESSION");
    
        if (user_session!=null){
            req.getSession().removeAttribute("USER_SESSION");
            resp.sendRedirect("/login.jsp");
        }else {
            resp.sendRedirect("/login.jsp");
    
        }
    }
    
  3. 进入主页的时候 要判断用户是否登入 在过滤器中实现

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        //ServletRequest   HttpServletRequest  因为监听器的ServletRequest是没有重定向方法的 需要强转
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
    
    
    
        if (request.getSession().getAttribute(Constant.USER_SESSION)==null){
            response.sendRedirect("/error.jsp");
        }
    
        chain.doFilter(request,response);
    }
    

    设置的常量USER_SESSION

    public class Constant {
        public final static String USER_SESSION="USER_SESSION";
        //因为这个session的ID经常被使用 我们可以把ID的key USER_SESSION 直接变成一个常量 这样每次调用直接写 constant.USER_SESSION
        //而在以后维护需要更改名字的时候 可以直接在这里改 如果是每次使用创建一个 那么修改起来会非常麻烦
    }
    

14 JDBC

什么是JDBC: Java 连接数据库

4.Javaweb基础入门_第65张图片

需要的jar包支持

  • java.sql
  • javax.sql
  • mysql-connector-java 连接驱动 (必须要导入)

实验环境搭建

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&character=utf-8";

    String username = "root";
    String password = "123456";

    //1.加载驱动
    Class.forName("com.mysql.jdbc.Driver");

    //2.连接数据库  connection代表数据库
    Connection connection = DriverManager.getConnection(url, username, password);

    //3.向数据库发送sql对象 statement
    Statement statement = connection.createStatement();

    //4.编写sql
    String sql = "select * from users";

    //5.执行sql  返回一个结果集
    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"));
    }


    //6.关闭连接 先创建后关闭
    rs.close();
    statement.close();
    connection.close();


}

导入数据库依赖


        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.31version>
        dependency>
    dependencies>

IDEA中连接数据库

4.Javaweb基础入门_第66张图片

JDBC固定步骤

  1. 加载驱动
  2. 连接数据库 代表数据库
  3. 向数据库发送sql的对象 statement
  4. 编写sql语句
  5. 执行sql
  6. 关闭连接

事务

要么都成功 要么都失败

ACID原则 保证数据的安全

开启事务
事物提交 commit()
事务回滚 rollback()
关闭事务
    
转账 
    A 1000元
    B 1000A(900)---100-->B(1100)  

Junit单元测试

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

简单实用(如果要测试这个test方法 需要 新建一个main 但是用@Test注解就可以直接运行这个方法)

@Test
public void test(){
    System.out.println("你好");
}

代码演示转账

package com.lhc.test;

import org.junit.Test;

import java.sql.*;

public class TestJDBC3 {

    @Test
    public void test() throws ClassNotFoundException, SQLException {

        Connection connection = null;
        try {
            //解决乱码问题 useUnicode=true&characterEncoding=utf8
            String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";

            String username = "root";
            String password = "123456";

            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");

            //2.连接数据库  connection代表数据库
            connection = DriverManager.getConnection(url, username, password);

            //3.通知数据库开启事务  关闭自动提交 相当于开启事务
            connection.setAutoCommit(false);

            //4.编写SQL
            String sql1 = "update account set money=money-100 where name='A'";
            connection.prepareStatement(sql1).executeUpdate();

            //制造错误
            int i = 1 / 0;

            String sql2 = "update account set money=money+100 where name='B'";
            connection.prepareStatement(sql2).executeUpdate();


            connection.commit();//以上两个SQL都执行成功了就提交时间
            System.out.println("");


        } catch (Exception e) {
            connection.rollback();
            e.printStackTrace();
        } finally {
            connection.close();
        }


    }
}

15 SMBMS(超市管理系统)

项目分析

4.Javaweb基础入门_第67张图片

数据库

4.Javaweb基础入门_第68张图片

准备项目搭建

项目如何搭建

考虑用不用Maven 依赖 Jar

Maven

  1. 搭建一个mavenweb项目

4.Javaweb基础入门_第69张图片

  1. 配置Tomcat

  2. 测试项目能否跑起来

  3. 导入项目中需要的jar包

        <dependencies>
    
            <dependency>
                <groupId>javax.servletgroupId>
                <artifactId>servlet-apiartifactId>
                <version>2.5version>
            dependency>
    
            <dependency>
                <groupId>javax.servlet.jspgroupId>
                <artifactId>jsp-apiartifactId>
                <version>2.1version>
            dependency>
    
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>5.1.31version>
            dependency>
            
            
            <dependency>
                <groupId>jstlgroupId>
                <artifactId>jstlartifactId>
                <version>1.2version>
            dependency>
            
            
            <dependency>
                <groupId>taglibsgroupId>
                <artifactId>standardartifactId>
                <version>1.1.2version>
            dependency>
    
    
        dependencies>
    
  4. 创建项目结构包

  5. 编写实体类

数据库编写

CREATE DATABASE `smbms`;

USE `smbms`;

DROP TABLE IF EXISTS `smbms_address`;

CREATE TABLE `smbms_address` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `contact` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人姓名',
  `addressDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '收货地址明细',
  `postCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '邮编',
  `tel` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人电话',
  `createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者',
  `creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) DEFAULT NULL COMMENT '修改者',
  `modifyDate` DATETIME DEFAULT NULL COMMENT '修改时间',
  `userId` BIGINT(20) DEFAULT NULL COMMENT '用户ID',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


INSERT  INTO `smbms_address`(`id`,`contact`,`addressDesc`,`postCode`,`tel`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`,`userId`) VALUES (1,'王丽','北京市东城区东交民巷44号','100010','13678789999',1,'2016-04-13 00:00:00',NULL,NULL,1),(2,'张红丽','北京市海淀区丹棱街3号','100000','18567672312',1,'2016-04-13 00:00:00',NULL,NULL,1),(3,'任志强','北京市东城区美术馆后街23号','100021','13387906742',1,'2016-04-13 00:00:00',NULL,NULL,1),(4,'曹颖','北京市朝阳区朝阳门南大街14号','100053','13568902323',1,'2016-04-13 00:00:00',NULL,NULL,2),(5,'李慧','北京市西城区三里河路南三巷3号','100032','18032356666',1,'2016-04-13 00:00:00',NULL,NULL,3),(6,'王国强','北京市顺义区高丽营镇金马工业区18号','100061','13787882222',1,'2016-04-13 00:00:00',NULL,NULL,3);


DROP TABLE IF EXISTS `smbms_bill`;

CREATE TABLE `smbms_bill` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `billCode` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '账单编码',
  `productName` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品名称',
  `productDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品描述',
  `productUnit` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品单位',
  `productCount` DECIMAL(20,2) DEFAULT NULL COMMENT '商品数量',
  `totalPrice` DECIMAL(20,2) DEFAULT NULL COMMENT '商品总额',
  `isPayment` INT(10) DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
  `createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
  `providerId` BIGINT(20) DEFAULT NULL COMMENT '供应商ID',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


INSERT  INTO `smbms_bill`(`id`,`billCode`,`productName`,`productDesc`,`productUnit`,`productCount`,`totalPrice`,`isPayment`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`,`providerId`) VALUES (2,'BILL2016_002','香皂、肥皂、药皂','日用品-皂类','块','1000.00','10000.00',2,1,'2016-03-23 04:20:40',NULL,NULL,13),(3,'BILL2016_003','大豆油','食品-食用油','斤','300.00','5890.00',2,1,'2014-12-14 13:02:03',NULL,NULL,6),(4,'BILL2016_004','橄榄油','食品-进口食用油','斤','200.00','9800.00',2,1,'2013-10-10 03:12:13',NULL,NULL,7),(5,'BILL2016_005','洗洁精','日用品-厨房清洁','瓶','500.00','7000.00',2,1,'2014-12-14 13:02:03',NULL,NULL,9),(6,'BILL2016_006','美国大杏仁','食品-坚果','袋','300.00','5000.00',2,1,'2016-04-14 06:08:09',NULL,NULL,4),(7,'BILL2016_007','沐浴液、精油','日用品-沐浴类','瓶','500.00','23000.00',1,1,'2016-07-22 10:10:22',NULL,NULL,14),(8,'BILL2016_008','不锈钢盘碗','日用品-厨房用具','个','600.00','6000.00',2,1,'2016-04-14 05:12:13',NULL,NULL,14),(9,'BILL2016_009','塑料杯','日用品-杯子','个','350.00','1750.00',2,1,'2016-02-04 11:40:20',NULL,NULL,14),(10,'BILL2016_010','豆瓣酱','食品-调料','瓶','200.00','2000.00',2,1,'2013-10-29 05:07:03',NULL,NULL,8),(11,'BILL2016_011','海之蓝','饮料-国酒','瓶','50.00','10000.00',1,1,'2016-04-14 16:16:00',NULL,NULL,1),(12,'BILL2016_012','芝华士','饮料-洋酒','瓶','20.00','6000.00',1,1,'2016-09-09 17:00:00',NULL,NULL,1),(13,'BILL2016_013','长城红葡萄酒','饮料-红酒','瓶','60.00','800.00',2,1,'2016-11-14 15:23:00',NULL,NULL,1),(14,'BILL2016_014','泰国香米','食品-大米','斤','400.00','5000.00',2,1,'2016-10-09 15:20:00',NULL,NULL,3),(15,'BILL2016_015','东北大米','食品-大米','斤','600.00','4000.00',2,1,'2016-11-14 14:00:00',NULL,NULL,3),(16,'BILL2016_016','可口可乐','饮料','瓶','2000.00','6000.00',2,1,'2012-03-27 13:03:01',NULL,NULL,2),(17,'BILL2016_017','脉动','饮料','瓶','1500.00','4500.00',2,1,'2016-05-10 12:00:00',NULL,NULL,2),(18,'BILL2016_018','哇哈哈','饮料','瓶','2000.00','4000.00',2,1,'2015-11-24 15:12:03',NULL,NULL,2);

DROP TABLE IF EXISTS `smbms_provider`;

CREATE TABLE `smbms_provider` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `proCode` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商编码',
  `proName` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商名称',
  `proDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商详细描述',
  `proContact` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商联系人',
  `proPhone` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系电话',
  `proAddress` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址',
  `proFax` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '传真',
  `createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
  `modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
  `modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


INSERT  INTO `smbms_provider`(`id`,`proCode`,`proName`,`proDesc`,`proContact`,`proPhone`,`proAddress`,`proFax`,`createdBy`,`creationDate`,`modifyDate`,`modifyBy`) VALUES (1,'BJ_GYS001','北京三木堂商贸有限公司','长期合作伙伴,主营产品:茅台、五粮液、郎酒、酒鬼酒、泸州老窖、赖茅酒、法国红酒等','张国强','13566667777','北京市丰台区育芳园北路','010-58858787',1,'2013-03-21 16:52:07',NULL,NULL),(2,'HB_GYS001','石家庄帅益食品贸易有限公司','长期合作伙伴,主营产品:饮料、水饮料、植物蛋白饮料、休闲食品、果汁饮料、功能饮料等','王军','13309094212','河北省石家庄新华区','0311-67738876',1,'2016-04-13 04:20:40',NULL,NULL),(3,'GZ_GYS001','深圳市泰香米业有限公司','初次合作伙伴,主营产品:良记金轮米,龙轮香米等','郑程瀚','13402013312','广东省深圳市福田区深南大道6006华丰大厦','0755-67776212',1,'2014-03-21 16:56:07',NULL,NULL),(4,'GZ_GYS002','深圳市喜来客商贸有限公司','长期合作伙伴,主营产品:坚果炒货.果脯蜜饯.天然花茶.营养豆豆.特色美食.进口食品.海味零食.肉脯肉','林妮','18599897645','广东省深圳市福龙工业区B2栋3楼西','0755-67772341',1,'2013-03-22 16:52:07',NULL,NULL),(5,'JS_GYS001','兴化佳美调味品厂','长期合作伙伴,主营产品:天然香辛料、鸡精、复合调味料','徐国洋','13754444221','江苏省兴化市林湖工业区','0523-21299098',1,'2015-11-22 16:52:07',NULL,NULL),(6,'BJ_GYS002','北京纳福尔食用油有限公司','长期合作伙伴,主营产品:山茶油、大豆油、花生油、橄榄油等','马莺','13422235678','北京市朝阳区珠江帝景1号楼','010-588634233',1,'2012-03-21 17:52:07',NULL,NULL),(7,'BJ_GYS003','北京国粮食用油有限公司','初次合作伙伴,主营产品:花生油、大豆油、小磨油等','王驰','13344441135','北京大兴青云店开发区','010-588134111',1,'2016-04-13 00:00:00',NULL,NULL),(8,'ZJ_GYS001','慈溪市广和绿色食品厂','长期合作伙伴,主营产品:豆瓣酱、黄豆酱、甜面酱,辣椒,大蒜等农产品','薛圣丹','18099953223','浙江省宁波市慈溪周巷小安村','0574-34449090',1,'2013-11-21 06:02:07',NULL,NULL),(9,'GX_GYS001','优百商贸有限公司','长期合作伙伴,主营产品:日化产品','李立国','13323566543','广西南宁市秀厢大道42-1号','0771-98861134',1,'2013-03-21 19:52:07',NULL,NULL),(10,'JS_GYS002','南京火头军信息技术有限公司','长期合作伙伴,主营产品:不锈钢厨具等','陈女士','13098992113','江苏省南京市浦口区浦口大道1号新城总部大厦A座903室','025-86223345',1,'2013-03-25 16:52:07',NULL,NULL),(11,'GZ_GYS003','广州市白云区美星五金制品厂','长期合作伙伴,主营产品:海绵床垫、坐垫、靠垫、海绵枕头、头枕等','梁天','13562276775','广州市白云区钟落潭镇福龙路20号','020-85542231',1,'2016-12-21 06:12:17',NULL,NULL),(12,'BJ_GYS004','北京隆盛日化科技','长期合作伙伴,主营产品:日化环保清洗剂,家居洗涤专卖、洗涤用品网、墙体除霉剂、墙面霉菌清除剂等','孙欣','13689865678','北京市大兴区旧宫','010-35576786',1,'2014-11-21 12:51:11',NULL,NULL),(13,'SD_GYS001','山东豪克华光联合发展有限公司','长期合作伙伴,主营产品:洗衣皂、洗衣粉、洗衣液、洗洁精、消杀类、香皂等','吴洪转','13245468787','山东济阳济北工业区仁和街21号','0531-53362445',1,'2015-01-28 10:52:07',NULL,NULL),(14,'JS_GYS003','无锡喜源坤商行','长期合作伙伴,主营产品:日化品批销','周一清','18567674532','江苏无锡盛岸西路','0510-32274422',1,'2016-04-23 11:11:11',NULL,NULL),(15,'ZJ_GYS002','乐摆日用品厂','长期合作伙伴,主营产品:各种中、高档塑料杯,塑料乐扣水杯(密封杯)、保鲜杯(保鲜盒)、广告杯、礼品杯','王世杰','13212331567','浙江省金华市义乌市义东路','0579-34452321',1,'2016-08-22 10:01:30',NULL,NULL);


DROP TABLE IF EXISTS `smbms_role`;

CREATE TABLE `smbms_role` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `roleCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色编码',
  `roleName` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色名称',
  `createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者',
  `creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) DEFAULT NULL COMMENT '修改者',
  `modifyDate` DATETIME DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


INSERT  INTO `smbms_role`(`id`,`roleCode`,`roleName`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`) VALUES (1,'SMBMS_ADMIN','系统管理员',1,'2016-04-13 00:00:00',NULL,NULL),(2,'SMBMS_MANAGER','经理',1,'2016-04-13 00:00:00',NULL,NULL),(3,'SMBMS_EMPLOYEE','普通员工',1,'2016-04-13 00:00:00',NULL,NULL);


DROP TABLE IF EXISTS `smbms_user`;

CREATE TABLE `smbms_user` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `userCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户编码',
  `userName` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户名称',
  `userPassword` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户密码',
  `gender` INT(10) DEFAULT NULL COMMENT '性别(1:女、 2:男)',
  `birthday` DATE DEFAULT NULL COMMENT '出生日期',
  `phone` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '手机',
  `address` VARCHAR(30) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址',
  `userRole` BIGINT(20) DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)',
  `createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
  `creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
  `modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
  `modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT  INTO `smbms_user`(`id`,`userCode`,`userName`,`userPassword`,`gender`,`birthday`,`phone`,`address`,`userRole`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`) VALUES (1,'admin','系统管理员','1234567',1,'1983-10-10','13688889999','北京市海淀区成府路207号',1,1,'2013-03-21 16:52:07',NULL,NULL),(2,'liming','李明','0000000',2,'1983-12-10','13688884457','北京市东城区前门东大街9号',2,1,'2014-12-31 19:52:09',NULL,NULL),(5,'hanlubiao','韩路彪','0000000',2,'1984-06-05','18567542321','北京市朝阳区北辰中心12号',2,1,'2014-12-31 19:52:09',NULL,NULL),(6,'zhanghua','张华','0000000',1,'1983-06-15','13544561111','北京市海淀区学院路61号',3,1,'2013-02-11 10:51:17',NULL,NULL),(7,'wangyang','王洋','0000000',2,'1982-12-31','13444561124','北京市海淀区西二旗辉煌国际16层',3,1,'2014-06-11 19:09:07',NULL,NULL),(8,'zhaoyan','赵燕','0000000',1,'1986-03-07','18098764545','北京市海淀区回龙观小区10号楼',3,1,'2016-04-21 13:54:07',NULL,NULL),(10,'sunlei','孙磊','0000000',2,'1981-01-04','13387676765','北京市朝阳区管庄新月小区12楼',3,1,'2015-05-06 10:52:07',NULL,NULL),(11,'sunxing','孙兴','0000000',2,'1978-03-12','13367890900','北京市朝阳区建国门南大街10号',3,1,'2016-11-09 16:51:17',NULL,NULL),(12,'zhangchen','张晨','0000000',1,'1986-03-28','18098765434','朝阳区管庄路口北柏林爱乐三期13号楼',3,1,'2016-08-09 05:52:37',1,'2016-04-14 14:15:36'),(13,'dengchao','邓超','0000000',2,'1981-11-04','13689674534','北京市海淀区北航家属院10号楼',3,1,'2016-07-11 08:02:47',NULL,NULL),(14,'yangguo','杨过','0000000',2,'1980-01-01','13388886623','北京市朝阳区北苑家园茉莉园20号楼',3,1,'2015-02-01 03:52:07',NULL,NULL),(15,'zhaomin','赵敏','0000000',1,'1987-12-04','18099897657','北京市昌平区天通苑3区12号楼',2,1,'2015-09-12 12:02:12',NULL,NULL);

pojo(实体类编写)

ORM映射 表-类映射

User类

import java.util.Date;
public class User {
   private Integer id; //id 
   private String userCode; //用户编码
   private String userName; //用户名称
   private String userPassword; //用户密码
   private Integer gender;  //性别
   private Date birthday;  //出生日期
   private String phone;   //电话
   private String address; //地址
   private Integer userRole;    //用户角色
   private Integer createdBy;   //创建者
   private Date creationDate; //创建时间
   private Integer modifyBy;     //更新者
   private Date modifyDate;   //更新时间
   
   private Integer age;//年龄
   private String userRoleName;    //用户角色名称


   public String getUserRoleName() {
   	return userRoleName;
   }
   public void setUserRoleName(String userRoleName) {
   	this.userRoleName = userRoleName;
   }
   public Integer getAge() {
   	Date date = new Date();
   	Integer age = date.getYear()-birthday.getYear();
   	return age;
   }
   public Integer getId() {
   	return id;
   }
   public void setId(Integer id) {
   	this.id = id;
   }
   public String getUserCode() {
   	return userCode;
   }
   public void setUserCode(String userCode) {
   	this.userCode = userCode;
   }
   public String getUserName() {
   	return userName;
   }
   public void setUserName(String userName) {
   	this.userName = userName;
   }
   public String getUserPassword() {
   	return userPassword;
   }
   public void setUserPassword(String userPassword) {
   	this.userPassword = userPassword;
   }
   public Integer getGender() {
   	return gender;
   }
   public void setGender(Integer gender) {
   	this.gender = gender;
   }
   public Date getBirthday() {
   	return birthday;
   }
   public void setBirthday(Date birthday) {
   	this.birthday = birthday;
   }
   public String getPhone() {
   	return phone;
   }
   public void setPhone(String phone) {
   	this.phone = phone;
   }
   public String getAddress() {
   	return address;
   }
   public void setAddress(String address) {
   	this.address = address;
   }
   public Integer getUserRole() {
   	return userRole;
   }
   public void setUserRole(Integer userRole) {
   	this.userRole = userRole;
   }
   public Integer getCreatedBy() {
   	return createdBy;
   }
   public void setCreatedBy(Integer createdBy) {
   	this.createdBy = createdBy;
   }
   public Date getCreationDate() {
   	return creationDate;
   }
   public void setCreationDate(Date creationDate) {
   	this.creationDate = creationDate;
   }
   public Integer getModifyBy() {
   	return modifyBy;
   }
   public void setModifyBy(Integer modifyBy) {
   	this.modifyBy = modifyBy;
   }
   public Date getModifyDate() {
   	return modifyDate;
   }
   public void setModifyDate(Date modifyDate) {
   	this.modifyDate = modifyDate;
   }

}

Bill类

import java.math.BigDecimal;
import java.util.Date;
public class Bill {
   private Integer id;   //id 
   private String billCode; //账单编码 
   private String productName; //商品名称 
   private String productDesc; //商品描述 
   private String productUnit; //商品单位
   private BigDecimal productCount; //商品数量 
   private BigDecimal totalPrice; //总金额
   private Integer isPayment; //是否支付 
   private Integer providerId; //供应商ID 
   private Integer createdBy; //创建者
   private Date creationDate; //创建时间
   private Integer modifyBy; //更新者
   private Date modifyDate;//更新时间
   
   private String providerName;//供应商名称
   
   
   public String getProviderName() {
   	return providerName;
   }
   public void setProviderName(String providerName) {
   	this.providerName = providerName;
   }
   public Integer getId() {
   	return id;
   }
   public void setId(Integer id) {
   	this.id = id;
   }
   public String getBillCode() {
   	return billCode;
   }
   public void setBillCode(String billCode) {
   	this.billCode = billCode;
   }
   public String getProductName() {
   	return productName;
   }
   public void setProductName(String productName) {
   	this.productName = productName;
   }
   public String getProductDesc() {
   	return productDesc;
   }
   public void setProductDesc(String productDesc) {
   	this.productDesc = productDesc;
   }
   public String getProductUnit() {
   	return productUnit;
   }
   public void setProductUnit(String productUnit) {
   	this.productUnit = productUnit;
   }
   public BigDecimal getProductCount() {
   	return productCount;
   }
   public void setProductCount(BigDecimal productCount) {
   	this.productCount = productCount;
   }
   public BigDecimal getTotalPrice() {
   	return totalPrice;
   }
   public void setTotalPrice(BigDecimal totalPrice) {
   	this.totalPrice = totalPrice;
   }
   public Integer getIsPayment() {
   	return isPayment;
   }
   public void setIsPayment(Integer isPayment) {
   	this.isPayment = isPayment;
   }
   
   public Integer getProviderId() {
   	return providerId;
   }
   public void setProviderId(Integer providerId) {
   	this.providerId = providerId;
   }
   public Integer getCreatedBy() {
   	return createdBy;
   }
   public void setCreatedBy(Integer createdBy) {
   	this.createdBy = createdBy;
   }
   public Date getCreationDate() {
   	return creationDate;
   }
   public void setCreationDate(Date creationDate) {
   	this.creationDate = creationDate;
   }
   public Integer getModifyBy() {
   	return modifyBy;
   }
   public void setModifyBy(Integer modifyBy) {
   	this.modifyBy = modifyBy;
   }
   public Date getModifyDate() {
   	return modifyDate;
   }
   public void setModifyDate(Date modifyDate) {
   	this.modifyDate = modifyDate;
   }
}

Role类

import java.util.Date;
public class Role {	
   private Integer id;   //id
   private String roleCode; //角色编码
   private String roleName; //角色名称
   private Integer createdBy; //创建者
   private Date creationDate; //创建时间
   private Integer modifyBy; //更新者
   private Date modifyDate;//更新时间
   
   public Integer getId() {
   	return id;
   }
   public void setId(Integer id) {
   	this.id = id;
   }
   public String getRoleCode() {
   	return roleCode;
   }
   public void setRoleCode(String roleCode) {
   	this.roleCode = roleCode;
   }
   public String getRoleName() {
   	return roleName;
   }
   public void setRoleName(String roleName) {
   	this.roleName = roleName;
   }
   public Integer getCreatedBy() {
   	return createdBy;
   }
   public void setCreatedBy(Integer createdBy) {
   	this.createdBy = createdBy;
   }
   public Date getCreationDate() {
   	return creationDate;
   }
   public void setCreationDate(Date creationDate) {
   	this.creationDate = creationDate;
   }
   public Integer getModifyBy() {
   	return modifyBy;
   }
   public void setModifyBy(Integer modifyBy) {
   	this.modifyBy = modifyBy;
   }
   public Date getModifyDate() {
   	return modifyDate;
   }
   public void setModifyDate(Date modifyDate) {
   	this.modifyDate = modifyDate;
   }
}

Provider类

import java.util.Date;
public class Provider {
   private Integer id;   //id
   private String proCode; //供应商编码
   private String proName; //供应商名称
   private String proDesc; //供应商描述
   private String proContact; //供应商联系人
   private String proPhone; //供应商电话
   private String proAddress; //供应商地址
   private String proFax; //供应商传真
   private Integer createdBy; //创建者
   private Date creationDate; //创建时间
   private Integer modifyBy; //更新者
   private Date modifyDate;//更新时间

   public Integer getId() {
   	return id;
   }
   public void setId(Integer id) {
   	this.id = id;
   }
   public String getProCode() {
   	return proCode;
   }
   public void setProCode(String proCode) {
   	this.proCode = proCode;
   }
   public String getProName() {
   	return proName;
   }
   public void setProName(String proName) {
   	this.proName = proName;
   }
   public String getProDesc() {
   	return proDesc;
   }
   public void setProDesc(String proDesc) {
   	this.proDesc = proDesc;
   }
   public String getProContact() {
   	return proContact;
   }
   public void setProContact(String proContact) {
   	this.proContact = proContact;
   }
   public String getProPhone() {
   	return proPhone;
   }
   public void setProPhone(String proPhone) {
   	this.proPhone = proPhone;
   }
   public String getProAddress() {
   	return proAddress;
   }
   public void setProAddress(String proAddress) {
   	this.proAddress = proAddress;
   }
   public String getProFax() {
   	return proFax;
   }
   public void setProFax(String proFax) {
   	this.proFax = proFax;
   }
   public Integer getCreatedBy() {
   	return createdBy;
   }
   public void setCreatedBy(Integer createdBy) {
   	this.createdBy = createdBy;
   }
   public Date getCreationDate() {
   	return creationDate;
   }
   public void setCreationDate(Date creationDate) {
   	this.creationDate = creationDate;
   }
   public Integer getModifyBy() {
   	return modifyBy;
   }
   public void setModifyBy(Integer modifyBy) {
   	this.modifyBy = modifyBy;
   }
   public Date getModifyDate() {
   	return modifyDate;
   }
   public void setModifyDate(Date modifyDate) {
   	this.modifyDate = modifyDate;
   }
}

编写基础公共类

数据库配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username=root
password=123456

编写数据库增删改查公共类

package com.lhc.dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class BaseDao {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    //静态代码块
    static {
        //通过类加载器 读取对应的资源
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
        Properties properties = new Properties();

        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");

    }

    //获取数据库的连接
    public static Connection getConnection()  {
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
            System.out.println("连接成功");
        } catch (Exception e) {
            System.out.println("连接失败");
            e.printStackTrace();
        }
        return connection;
    }

    //编写查询公共类
    public static ResultSet execute(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) throws SQLException {

        //预编译的sql 在后面直接执行就可以了
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //因为 preparedStatement.setObject是从 1 开始的
            preparedStatement.setObject(i + 1, params[i]);
        }
        resultSet = preparedStatement.executeQuery();

        return resultSet;

    }

    //编写增删改公共类
    public static int execute(Connection connection, PreparedStatement preparedStatement, String sql, Object[] params) throws SQLException {
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            //因为 preparedStatement.setObject是从 1 开始的
            preparedStatement.setObject(i + 1, params[i]);
        }
        int i = preparedStatement.executeUpdate();

        return i;

    }

    //释放资源
    public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
        boolean flag = true;
        if (resultSet != null) {
            try {
                resultSet.close();
                //GC回收
                resultSet = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
                //GC回收
                preparedStatement = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        if (connection != null) {
            try {
                connection.close();
                //GC回收
                resultSet = null;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        return flag;
    }
}

编写字符编码过滤器


<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">
    
    
    <filter>
        <filter-name>CharacterEncodingFilterfilter-name>
        <filter-class>com.lhc.filter.CharacterEncodingFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>


web-app>

导入静态资源

码云服务器里有

https://gitee.com/babobenNB/smbms?_from=gitee_search

登入功能实现

4.Javaweb基础入门_第70张图片

  1. 编写前端页面

  2. 设置首页

    web.xml

    
    <welcome-file-list>
        <welcome-file>login.jspwelcome-file>
    welcome-file-list>
    
  3. 编写 dao层用户登入的窗口

    package com.lhc.dao.user;
    
    import com.lhc.pojo.User;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    
    public interface UserDao {
        //得到要登入的用户
        public User getLoginUser(Connection connection,String userCode) throws SQLException;
    }
    
  4. 编写dao接口的实现类

    package com.lhc.dao.user;
    
    import com.lhc.dao.BaseDao;
    import com.lhc.pojo.User;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class UserDaoImpl implements UserDao {
        public User getLoginUser(Connection connection, String userCode) throws SQLException {
            PreparedStatement pstm = null;
            ResultSet rs = null;
            User user = null;
    
            if (connection != null) {
                String sql = "select * from smbms_user where userCode=?";
                Object[] params = {userCode};
    
    
                BaseDao.executeQuery(connection, pstm, rs, sql, params);
    
                if (rs.next()) {
                    user = new User();
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setUserCode(rs.getString("userCode"));
                    user.setUserName(rs.getString("userName"));
                    user.setUserPassword(rs.getString("userPassword"));
                    user.setGender(rs.getInt("gender"));
                    user.setBirthday(rs.getDate("birthday"));
                    user.setPhone(rs.getString("phone"));
                    user.setAddress(rs.getString("address"));
                    user.setUserRole(rs.getInt("userRole"));
                    user.setCreatedBy(rs.getInt("createdBy"));
                    user.setCreationDate(rs.getTimestamp("creationDate"));
                    user.setModifyBy(rs.getInt("modifyBy"));
                    user.setModifyDate(rs.getTimestamp("modifyDate"));
                }
                BaseDao.closeResource(null, pstm, rs);
    
    
            }
            return user;
        }
    }
    
  5. 业务层接口

    package com.lhc.service;
    
    import com.lhc.pojo.User;
    
    public interface UserService {
        //用户登入
        public User login(String userCode,String password);
    }
    
  6. 业务层实现类

    package com.lhc.service;
    
    import com.lhc.dao.BaseDao;
    import com.lhc.dao.user.UserDao;
    import com.lhc.dao.user.UserDaoImpl;
    import com.lhc.pojo.User;
    import org.junit.Test;
    
    import java.sql.Connection;
    
    
    public class UserServiceImpl implements UserService {
        private UserDao userDao;
    
        public UserServiceImpl(){
            userDao= new UserDaoImpl();
        }
    
        public User login(String userCode, String password) {
            //业务层都会调用Dao层 所以我们要引入Dao层
            Connection connection=null;
            User user=null;
    
    
            try {
                connection= BaseDao.getConnection();
                System.out.println("连接成功");
                //通过业务层调用对应的具体的数据库操作
                user = userDao.getLoginUser(connection, userCode, password);
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                BaseDao.closeResource(connection,null,null);
            }
            return user;
        }
    
    }
    
    
  7. 编写servlet

    package com.lhc.servlet.user;
    
    import com.lhc.pojo.User;
    import com.lhc.service.UserService;
    import com.lhc.service.UserServiceImpl;
    import com.lhc.util.Constant;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginServlet extends HttpServlet {
    
        //servlet 控制层 调用业务层代码
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("进入LoginServlet---start...");
    
            //获取用户名和密码
            String userCode = req.getParameter("userCode");
            String userpassword = req.getParameter("userpassword");
    
            //和数据库中的密码进行对比 调用业务层
            UserServiceImpl userService = new UserServiceImpl();
            User user = userService.login(userCode, userpassword);//这里已经把登入的人给查出来了
    
            if (user!=null){//查有此人 可以登入
                //将用户的信息 放到Session中
                req.getSession().setAttribute(Constant.USER_SESSION,user);
    
                //跳转到主页
                resp.sendRedirect("jsp/frame.jsp");
    
    
            }else {//查无此人
                req.setAttribute("error","用户或者密码错误");
                req.getRequestDispatcher("login.jsp").forward(req,resp);
    
            }
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  8. 注册Servlet

    <servlet>
        <servlet-name>LoginServletservlet-name>
        <servlet-class>com.lhc.servlet.user.LoginServletservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>LoginServletservlet-name>
        <url-pattern>/login.dourl-pattern>
    servlet-mapping>
    
  9. 测试访问 确保以上功能成功!

登入功能优化

注销功能

思路 移除session 返回登入页面

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户的Constant.USER_SESSION
        req.getSession().removeAttribute(Constant.USER_SESSION);
        resp.sendRedirect(req.getContextPath()+"/login.jsp");//返回登入页面  req.getContextPath()是到webapp路径下
    }

xml注册


<servlet>
    <servlet-name>LogoutServletservlet-name>
    <servlet-class>com.lhc.servlet.user.LogoutServletservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>LogoutServletservlet-name>
    <url-pattern>/jsp/logout.dourl-pattern>
servlet-mapping>

登入拦截优化

查看session是否存在

过滤器

public void doFilter(ServletRequest req ,ServletResponse resp, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    //过滤器 从session中获取用户
    User user = (User) request.getSession().getAttribute(Constant.USER_SESSION);

    if (user==null){//已经被移除或者注销了 或者未登入
        response.sendRedirect("smbms/error.jsp");
    }else {
        chain.doFilter(req,resp);
    }


}

web.xml


<filter>
    <filter-name>SysFilterfilter-name>
    <filter-class>com.lhc.filter.SysFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>SysFilterfilter-name>
    <url-pattern>/jsp/*url-pattern>
filter-mapping>

登入 注销 拦截 完成

密码修改

  1. 导入前端页面

  2. 写项目 从底层向上写

4.Javaweb基础入门_第71张图片

  1. UserDao接口

    public int updatePwd(Connection connection,int id,String password) throws SQLException;
    
  2. UserDao接口实现类

    public int updatePwd(Connection connection, int id, String password) throws SQLException {
        PreparedStatement pstm = null;
        int execute = 0;
    
        if (connection != null) {
            String sql = "update smbms_user set userPassword=? where id=?";
            Object params[] = {password, id};
            execute = BaseDao.execute(connection, pstm, sql, params);
            BaseDao.closeResource(null, pstm, null);
        }
    
        return execute;
    }
    
  3. Userservice接口

    //根据user ID 修改密码
    public boolean updatePwd(int id, String password) throws SQLException;
    
  4. UserService实现类

    public boolean updatePwd(int id, String password) throws SQLException {
        Connection connection = null;
        boolean flag = false;
    
        connection = BaseDao.getConnection();
    
    
        try {
            //修改密码
            if (userDao.updatePwd(connection, id, password) > 0) {
                flag = true;
            }
    
        } catch (Exception e) {
            e.printStackTrace();
            BaseDao.closeResource(connection, null, null);
        }
        return flag;
    
    }
    
  5. Servlet层

     //修改密码
        public void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //从Session里拿ID
            Object o = req.getSession().getAttribute(Constant.USER_SESSION);
            boolean flag = false;
    
            String newpassword = req.getParameter("newpassword");
    
            if (o != null && !StringUtils.isEmptyOrWhitespaceOnly(newpassword)) {
    
                try {
                    UserServiceImpl userService = new UserServiceImpl();
                    flag = userService.updatePwd(((User) o).getId(), newpassword);
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
    
                if (flag) {
                        req.setAttribute("message", "修改密码成功,请退出 使用新密码登入");
                        //密码修改成功 移除当前session
                        req.getSession().removeAttribute(Constant.USER_SESSION);
    
                    } else {
                        //密码修改失败
                        req.setAttribute("message", "修改密码失败");
    
                    }
    
            } else {
                //密码修改失败
                req.setAttribute("message", "修改密码有问题");
            }
            req.getRequestDispatcher("pwdmodify.jsp").forward(req, resp);
        }
    
  6. 记得实现服用 需要提取出方法

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
    
        if (method.equals("savepwd")&&method!=null){
            this.update(req,resp);
        }
    }
    
  7. 测试成功

优化密码修改 使用Ajax

  1. 阿里巴巴的fastjson

    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.61version>
    dependency>
    
  2. 后台代码

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method.equals("savepwd") && method != null) {
            try {
                this.update(req, resp);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }else if (method.equals("pwdmodify")&&method != null){
            Object o = req.getSession().getAttribute(Constant.USER_SESSION);
            String oldpassword = req.getParameter("oldpassword");
    
            //万能的Map  结果集
            HashMap<String, String> resultMap = new HashMap<String,String>();
            if (o==null){
                //session失效了 或者过期
                resultMap.put("result","sessionerror");
            }else if (StringUtils.isEmptyOrWhitespaceOnly(oldpassword)){
                resultMap.put("result","error");
            }else {
                String userPassword = ((User) o).getUserPassword();//session中用户的密码
                if (oldpassword.equals(userPassword)){
                    resultMap.put("result","true");
                }else {
                    resultMap.put("result","false");
                }
            }
    
            //返回一个json文件
            resp.setContentType("application/json");;
            PrintWriter writer = resp.getWriter();
            //JSONArray 阿里巴巴的json工具类  转换格式
            /*
                resultMap.put("result","sessionerror")
                转换成json的格式{key:value}
            */
            writer.write(JSONArray.toJSONString(resultMap));
            writer.flush();
            writer.close();
        }
    }
    

用户管理实现

思路

4.Javaweb基础入门_第72张图片

  1. 导入分页的工具类

  2. 用户列表页面导入

    userlist.jsp

1 获取用户数量

1.UserDao

public int getUserCount(String username,int userRole) throws SQLException;

2.UserDaoImpl

//根据用户名或者角色查询用户总数
public int getUserCount(String username, int userRole) throws SQLException {

    PreparedStatement pstm = null;
    ResultSet rs = null;
    Integer count = 0;
    Connection connection = BaseDao.getConnection();

    if (connection != null) {
        StringBuffer sql = new StringBuffer();
        sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole=r.id");
        ArrayList<Object> list = new ArrayList<Object>();//存放我们的数据

        if (!StringUtils.isNullOrEmpty(username)) {
            sql.append("and u.username like ?");
            list.add("%" + username + "%");//index:0
        }
        if (userRole > 0) {
            sql.append(" and u.userRole =?");
            list.add(userRole);//index:1
        }
        //怎么List转换为数组
        Object[] params = list.toArray();

        System.out.println("UserDaoImpl-->getUserCount:" + sql.toString());

        rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
        if (rs.next()) {
            count = rs.getInt("count");//从结果集中获得数量
        }
        BaseDao.closeResource(connection, pstm, rs);

    }
    return count;

}

3.UserService

//查询记录数
public int getUserCount(String username,int userRole);

4.UserServiceImpl

public int getUserCount(String username, int userRole) {
    int count=0;
    Connection connection = null;
    try {

        connection = BaseDao.getConnection();
        count = userDao.getUserCount(username, userRole);

    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
    return count;
}

5.Servlet

2 获取用户列表

1.UserDao

//获取用户列表
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)throws Exception;

2.UserDaoImpl

public List<User> getUserList(Connection connection,String userName, int userRole, int currentPageNo, int pageSize) throws Exception {
    // TODO Auto-generated method stub
    PreparedStatement pstm = null;
    ResultSet rs = null;
    List<User> userList = new ArrayList<User>();
    if(connection != null){
        StringBuffer sql = new StringBuffer();
        sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id");
        List<Object> list = new ArrayList<Object>();
        if(!StringUtils.isNullOrEmpty(userName)){
            sql.append(" and u.userName like ?");
            list.add("%"+userName+"%");
        }
        if(userRole > 0){
            sql.append(" and u.userRole = ?");
            list.add(userRole);
        }
        //在数据库中 分页使用   limit startIndex,pageSize 总数
        //当前页 (当前页-1)*页面大小
        // 0,5   1  0    01234
        //6,5   2  6    56789
        //11,5  3  10
        sql.append(" order by creationDate DESC limit ?,?");
        currentPageNo = (currentPageNo-1)*pageSize;
        list.add(currentPageNo);
        list.add(pageSize);

        Object[] params = list.toArray();
        System.out.println("sql ----> " + sql.toString());
        rs = BaseDao.execute(connection,pstm, rs, sql.toString(), params);
        while(rs.next()){
            User _user = new User();
            _user.setId(rs.getInt("id"));
            _user.setUserCode(rs.getString("userCode"));
            _user.setUserName(rs.getString("userName"));
            _user.setGender(rs.getInt("gender"));
            _user.setBirthday(rs.getDate("birthday"));
            _user.setPhone(rs.getString("phone"));
            _user.setUserRole(rs.getInt("userRole"));
            _user.setUserRoleName(rs.getString("userRoleName"));
            userList.add(_user);
        }
        BaseDao.closeResource(null, pstm, rs);
    }
    return userList;
}

3.Userservice

//通过条件查询 -userList
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);

4.UserserviceImpl

public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
    // TODO Auto-generated method stub
    Connection connection = null;
    List<User> userList = null;
    System.out.println("queryUserName ---- > " + queryUserName);
    System.out.println("queryUserRole ---- > " + queryUserRole);
    System.out.println("currentPageNo ---- > " + currentPageNo);
    System.out.println("pageSize ---- > " + pageSize);
    try {
        connection = BaseDao.getConnection();
        userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        BaseDao.closeResource(connection, null, null);
    }
    return userList;
}

3.获取角色操作

为了我们职责同一 可以把角色的操作单独放在一个包中 和POJO类对应

1.RoleDao

//获取角色列表
public List<Role> getRoleList(Connection connection)throws SQLException;

2.RoleDaoImpl

//获取角色列表
public List<Role> getRoleList(Connection connection) throws SQLException {
    PreparedStatement pstm=null;
    ResultSet rs=null;
    ArrayList<Role> roleList = new ArrayList<Role>();
    if (connection!=null){

        String sql="select * from smbms_role";
        Object[] params={};
        rs=BaseDao.execute(connection,pstm,rs,sql,params);

        while (rs.next()){
            Role role = new Role();
            role.setId(rs.getInt("id"));
            role.setRoleCode(rs.getString("rolename"));
            role.setRoleName(rs.getString("roleCode"));
            roleList.add(role);
        }
        BaseDao.closeResource(connection,pstm,rs);

    }
    return roleList;
}

3.RoleService

public List<Role> getRoleList();

4.RoleServiceImpl

//引入Dao
private RoleDao roleDao;
public RoleServiceImpl() {
    roleDao= new RoleDaoImpl();
}

public List<Role> getRoleList() {
    Connection connection = null;
    List<Role> roleList=null;
    try {
        connection=BaseDao.getConnection();
        roleList= roleDao.getRoleList(connection);
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        BaseDao.closeResource(connection,null,null);
    }
    return roleList;
}

4.用户显示的servlet

  1. 获取用户全的数据(查询)
  2. 判断请求是否需要执行 看参数的值判断
  3. 为了实现分页 需要计算出当前页面和总页面 页面大小
  4. 用户列表展示
  5. 返回前段
//query方法
public void query(HttpServletRequest req, HttpServletResponse resp){

    //查询用户列表

    //从前端获取数据;
    String queryUserName = req.getParameter("queryname");
    String temp = req.getParameter("queryUserRole");
    String pageIndex = req.getParameter("pageIndex");
    int queryUserRole = 0;

    //获取用户列表
    UserServiceImpl userService = new UserServiceImpl();
    List<User> userList = null;

    //第一次走这个请求,一定是第一页,页面大小固定的;
    int pageSize = 5; //可以把这个些到配置文件中,方便后期修改;
    int currentPageNo = 1;

    if (queryUserName ==null){
        queryUserName = "";
    }
    if (temp!=null && !temp.equals("")){
        queryUserRole = Integer.parseInt(temp);  //给查询赋值!0,1,2,3
    }
    if (pageIndex!=null){
        currentPageNo = Integer.parseInt(pageIndex);
    }

    //获取用户的总数 (分页:  上一页,下一页的情况)
    int totalCount = userService.getUserCount(queryUserName, queryUserRole);
    //总页数支持
    PageSupport pageSupport = new PageSupport();
    pageSupport.setCurrentPageNo(currentPageNo);
    pageSupport.setPageSize(pageSize);
    pageSupport.setTotalCount(totalCount);

    int totalPageCount = ((int)(totalCount/pageSize))+1;

    //控制首页和尾页
    //如果页面要小于1了,就显示第一页的东西
    if (currentPageNo<1){
        currentPageNo = 1;
    }else if (currentPageNo>totalPageCount){ //当前页面大于了最后一页;
        currentPageNo = totalPageCount;
    }

    //获取用户列表展示
    userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
    req.setAttribute("userList",userList);

    RoleServiceImpl roleService = new RoleServiceImpl();//用户名需要给下拉框里传值 因为前端用jstl表达式帮我们拆解这个List 所以我们传入List类型就行
    List<Role> roleList = roleService.getRoleList();
    req.setAttribute("roleList",roleList);
    req.setAttribute("totalCount",totalCount);
    req.setAttribute("currentPageNo",currentPageNo);
    req.setAttribute("totalPageCount",totalPageCount);
    req.setAttribute("queryUserName",queryUserName);
    req.setAttribute("queryUserRole",queryUserRole);


    //返回前端
    try {
        req.getRequestDispatcher("userlist.jsp").forward(req,resp);
    } catch (ServletException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

你可能感兴趣的:(Javaweb)