JavaWeb学习笔记

一、基本概念

  1. JavaWeb:在java中动态web资源的开发统称JavaWeb。
  2. Web应用程序:可以提供给浏览器访问的程序。
  3. web应用程序编写完毕后,若想提供给外界访问,需要一个服务器来统一管理。

二、web服务器

  1. ASP:微软公司提供,在html中嵌入VB脚本;C#语言。
  2. PHP:开发速度快,功能很强大,跨平台,代码很简单;无法承载大访问量。
  3. JSP/servlet:sun公司主推B/S架构,基于JAVA开发,可以承载3高(高并发、高性能、高可用)带来的问题。
  4. web服务器:服务器是一种被动操作,用来处理用户的一些请求和给用户相应一些信息。
  5. Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
  6. Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
  7. 目前Tomcat最新版本为10.0.5。
  8. jdk中jt.jar为java的核心jar包。

三、Tomcat基础

  1. 安装Tomcat:到官网https://tomcat.apache.org/下载Tomcat9.0版本;解压该文件到指定目录。
  2. 启动或关闭Tomcat:startup与书shutdown,测试Tomcat是否启动http://localhost:8080/。
  3. 安装过程中可能存在的问题:
    (1) java环境变量没有配置。
    (2) 闪退问题:需要解决兼容性。
    (3) 乱码问题:配置文件中设置。
  4. server.xml配置文件
    (1) 可以配置启动的端口
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

Tomcat默认端口为8080,MySQL为3306,http:80,https:443.
(2) 可以修改主机名:默认主机名为localhost–>127.0.0.1,默认网站存放位置为webapps。
(3) 可以在操作系统的hosts文件、Tomcat的server.xml文件中修改,则访问时可以输入http://www.lwp.com:8080.

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
//修改server.xml
      <Host name="www.lwp.com"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
//修改hosts,增加一行
	127.0.0.1 	www.lwp.com
  1. 高难度面试题:网站是如何进行访问的:
    (1) 输入网站域名,回车
    (2) 检查本机的hosts配置文件中是否存在这个域名映射。
    (3) 有:则直接返回该域名对应的IP地址,该IP地址中有我们可以直接访问的web程序,则直接访问。
    (4) 没有:则到DNS服务器上找,找到就返回,找不到就返回未找到。
  2. 发布一个web网站:不会就模仿
    (1) 将自己开发的web程序放在Tomcat指定文件夹(webapps)下,就可以访问。
    (2) 网站的结构:
---webapps:Tomcat服务器的web目录
    --root
    --lwp:开发网站的目录名
       -- WEB-INF
          --classes:开发的class文件
          --lib:网站所依赖的jar包
          --web.xml:网站的配置文件
       --index.html:默认的网页
       --static:资源文件
         --css
           --style.css
         --js
         --images
       。。。  

四、http

  1. 什么是http:HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准;HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
  2. http的两个版本:
    (1) http1.0:HTTP/1.0,客户端可以与Web服务器连接后,只能获得一个web资源,断开连接。
    (2) http2.0:HTTP/1.1,客户端可以与Web服务器连接后,可以获得多个web资源。
  3. Http请求:
    (1) 请求行:请求方式有get/post/HEAD/DELETE/PUT/TRACT…,
    (2) get方式:能够携带的参数比较小,大小由限制,会在浏览器的URL地址栏显示数据内容,不安全但高效。
    (3) post方式:能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全但不高效。
    (4) 消息头:
协议头说明示例状态
Accept可接受的响应内容类型(Content-Types)。Accept: text/plain固定
Accept-Charset可接受的字符集Accept-Charset: utf-8固定
Accept-Encoding可接受的响应内容的编码方式。Accept-Encoding: gzip, deflate固定
Accept-Language可接受的响应内容语言列表。Accept-Language: en-US固定
Accept-Datetime可接受的按照时间来表示的响应内容版本Accept-Datetime: Sat, 26 Dec 2015 17:30:00 GMT临时
Authorization用于表示HTTP协议中需要认证资源的认证信息Authorization: Basic OSdjJGRpbjpvcGVuIANlc2SdDE==固定
Cache-Control用来指定当前的请求/回复中的,是否使用缓存机制。Cache-Control: no-cache固定
Connection客户端(浏览器)想要优先使用的连接类型Connection: keep-alive Connection: Upgrade固定
Cookie由之前服务器通过Set-Cookie(见下文)设置的一个HTTP协议CookieCookie: $Version=1; Skin=new;固定:标准
Content-Length以8进制表示的请求体的长度Content-Length: 348固定
Content-MD5请求体的内容的二进制 MD5 散列值(数字签名),以 Base64 编码的结果Content-MD5: oD8dH2sgSW50ZWdyaIEd9D==废弃
Content-Type请求体的MIME类型 (用于POST和PUT请求中)Content-Type: application/x-www-form-urlencoded固定
Date发送该消息的日期和时间(以RFC 7231中定义的"HTTP日期"格式来发送)Date: Dec, 26 Dec 2015 17:30:00 GMT固定
Expect表示客户端要求服务器做出特定的行为Expect: 100-continue固定
From发起此请求的用户的邮件地址From: user@itbilu.com固定
Host表示服务器的域名以及服务器所监听的端口号。如果所请求的端口是对应的服务的标准端口(80),则端口号可以省略。Host: www.itbilu.com:80 Host: www.itbilu.com固定
If-Match仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要用于像 PUT 这样的方法中,仅当从用户上次更新某个资源后,该资源未被修改的情况下,才更新该资源。If-Match: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Modified-Since允许在对应的资源未被修改的情况下返回304未修改If-Modified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
If-None-Match允许在对应的内容未被修改的情况下返回304未修改( 304 Not Modified ),参考 超文本传输协议 的实体标记If-None-Match: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Range如果该实体未被修改过,则向返回所缺少的那一个或多个部分。否则,返回整个新的实体If-Range: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Unmodified-Since仅当该实体自某个特定时间以来未被修改的情况下,才发送回应。If-Unmodified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
Max-Forwards限制该消息可被代理及网关转发的次数。Max-Forwards: 10固定
Origin发起一个针对跨域资源共享的请求(该请求要求服务器在响应中加入一个Access-Control-Allow-Origin的消息头,表示访问控制所允许的来源)。Origin: http://www.itbilu.com固定: 标准
Pragma与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。Pragma: no-cache固定
Proxy-Authorization用于向代理进行认证的认证信息。Proxy-Authorization: Basic IOoDZRgDOi0vcGVuIHNlNidJi2==固定
Range表示请求某个实体的一部分,字节偏移以0开始。Range: bytes=500-999固定
Referer表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。Referer其实是Referrer这个单词,但RFC制作标准时给拼错了,后来也就将错就错使用Referer了。Referer: http://itbilu.com/nodejs固定
TE浏览器预期接受的传输时的编码方式:可使用回应协议头Transfer-Encoding中的值(还可以使用"trailers"表示数据传输时的分块方式)用来表示浏览器希望在最后一个大小为0的块之后还接收到一些额外的字段。TE: trailers,deflate固定
User-Agent浏览器的身份标识字符串}User-Agent: Mozilla/……固定
Upgrade要求服务器升级到一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Via告诉服务器,这个请求是由哪些代理发出的。Via: 1.0 fred, 1.1 itbilu.com.com (Apache/1.1)固定
Warning一个一般性的警告,表示在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
  1. Http响应:
    (1) 常用的HTTP响应头
响应头说明示例状态
Access-Control-Allow-Origin指定哪些网站可以跨域源资源共享Access-Control-Allow-Origin: *临时
Accept-Patch指定服务器所支持的文档补丁格式Accept-Patch: text/example;charset=utf-8固定
Accept-Ranges服务器所支持的内容范围Accept-Ranges: bytes固定
Age响应对象在代理缓存中存在的时间,以秒为单位Age: 12固定
Allow对于特定资源的有效动作;Allow: GET, HEAD固定
Cache-Control通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒Cache-Control: max-age=3600固定
Connection针对该连接所预期的选项Connection: close固定
Content-Disposition对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开。Content-Disposition: attachment; filename=“fname.ext”固定
Content-Encoding响应资源所使用的编码类型。Content-Encoding: gzip固定
Content-Language响就内容所使用的语言Content-Language: zh-cn固定
Content-Length响应消息体的长度,用8进制字节表示Content-Length: 348固定
Content-Location所返回的数据的一个候选位置Content-Location: /index.htm固定
Content-Range如果是响应部分消息,表示属于完整消息的哪个部分Content-Range: bytes 21010-47021/47022固定
Content-Type当前内容的MIME类型Content-Type: text/html; charset=utf-8固定
Date此条消息被发送时的日期和时间(以RFC 7231中定义的"HTTP日期"格式来表示)Date: Tue, 15 Nov 1994 08:12:31 GMT固定
ETag对于某个资源的某个特定版本的一个标识符,通常是一个 消息散列ETag: “737060cd8c284d8af7ad3082f209582d”固定
Expires指定一个日期/时间,超过该时间则认为此回应已经过期Expires: Thu, 01 Dec 1994 16:00:00 GMT固定: 标准
Last-Modified所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT固定
Link用来表示与另一个资源之间的类型关系,此类型关系是在RFC 5988中定义Link: ; rel=“alternate”固定
Location用于在进行重定向,或在创建了某个新资源时使用。Location: http://www.itbilu.com/nodejs固定
P3PP3P策略相关设置P3P: CP="This is not a P3P policy!固定
Pragma与具体的实现相关,这些响应头可能在请求/回应链中的不同时候产生不同的效果Pragma: no-cache固定
Proxy-Authenticate要求在访问代理时提供身份认证信息。Proxy-Authenticate: Basic固定
Public-Key-Pins用于防止中间攻击,声明网站认证中传输层安全协议的证书散列值Public-Key-Pins: max-age=2592000; pin-sha256=“……”;固定
Refresh用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。Refresh: 5; url=http://itbilu.com
Retry-After如果某个实体临时不可用,那么此协议头用于告知客户端稍后重试。其值可以是一个特定的时间段(以秒为单位)或一个超文本传输协议日期。•示例1:Retry-After: 120•示例2: Retry-After: Dec, 26 Dec 2015 17:30:00 GMT固定
Server服务器的名称Server: nginx/1.6.3固定
Set-Cookie设置HTTP cookieSet-Cookie: UserID=itbilu; Max-Age=3600; Version=1固定: 标准
Status通用网关接口的响应头字段,用来说明当前HTTP连接的响应状态。Status: 200OK
TrailerTrailer用户说明传输中分块编码的编码信息Trailer: Max-Forwards固定
Transfer-Encoding用表示实体传输给用户的编码形式。包括:chunked、compress、 deflate、gzip、identity。Transfer-Encoding: chunked固定
Upgrade要求客户端升级到另一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Vary告知下游的代理服务器,应当如何对以后的请求协议头进行匹配,以决定是否可使用已缓存的响应内容而不是重新从原服务器请求新的内容。Vary: *固定
Via告知代理服务器的客户端,当前响应是通过什么途径发送的。Via: 1.0 fred, 1.1 itbilu.com (nginx/1.6.3)固定
Warning一般性警告,告知在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
WWW-Authenticate表示在请求获取这个实体时应当使用的认证模式。WWW-Authenticate: Basic固定
(2) HTTP状态码
分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误
HTTP状态码列表
状态码状态码英文名称中文描述
100Continue继续。客户端应继续其请求
101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200OK请求成功。一般用于GET与POST请求
201Created已创建。成功请求并创建了新的资源
202Accepted已接受。已经接受请求,但未处理完成
203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205Reset Content重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206Partial Content部分内容。服务器成功处理了部分GET请求
300Multiple Choices多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303See Other查看其它地址。与301类似。使用GET和POST请求查看
304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305Use Proxy使用代理。所请求的资源必须通过代理访问
306Unused已经被废弃的HTTP状态码
307Temporary Redirect临时重定向。与302类似。使用GET请求重定向
400Bad Request客户端请求的语法错误,服务器无法理解
401Unauthorized请求要求用户的身份认证
402Payment Required保留,将来使用
403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求
404Not Found服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405Method Not Allowed客户端请求中的方法被禁止
406Not Acceptable服务器无法根据客户端请求的内容特性完成请求
407Proxy Authentication Required请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408Request Time-out服务器等待客户端发送的请求时间过长,超时
409Conflict服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410Gone客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息
412Precondition Failed客户端请求信息的先决条件错误
413Request Entity Too Large由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414Request-URI Too Large请求的URI过长(URI通常为网址),服务器无法处理
415Unsupported Media Type服务器无法处理请求附带的媒体格式
416Requested range not satisfiable客户端请求的范围无效
417Expectation Failed服务器无法满足Expect的请求头信息
500Internal Server Error服务器内部错误,无法完成请求
501Not Implemented服务器不支持请求的功能,无法完成请求
502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求
505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理

五、Maven

  1. Maven项目架构管理工具:用来方便导入jar包。其核心思想是约定大于配置,有约束不要违反。
  2. 到官网https://maven.apache.org/下载apache-maven-3.6.1,解压即可。
  3. 配置环境变量
    (1) M2_HOME:E:\devlopment\apache-maven-3.6.1\bin
    (2) MAVEN_HOME:E:\devlopment\apache-maven-3.6.1
    (3) 在path变量中添加:%MAVEN_HOME%\bin。
    (4) 在cmd下运行mvn -version,测试Maven是否安装成功,配置正确。
  4. 阿里云镜像:该网站为国外网站,为加快下载速度,建议使用阿里云镜像。
//在sesetting.xml中增加阿里云镜像
    <mirror>
      <id>nexus-aliyun</id>
      <name>nexus-aliyun</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  1. 配置本地仓库:localRepository
//先建一目录maven-repo
 <localRepository>E:\devlopment\apache-maven-3.6.1\maven-repo</localRepository>
  1. 在idea中使用Maven,利用模板创建
    (1) 配置Maven项目:启动idea——>点击file菜单——>选择new project——>选择Maven并勾选create from archetype;并查看Project Jdk目录是否正确——>选择maven-archetype-webapp(提示:A simple Java Web application )——>next——>填写公司名称groupID(com.sxsl),项目名称ArtifactID(JavaWeb-01-maven)——>next——>选择maven的home目录;选择用户的配置文件;选择本地仓库(按照maven的目录、setting.xml文件、本地仓库进行配置)——>next——>点击finish。
    (2) 等待项目初始化完毕;出现BUILD SUCCESS,说明项目搭建成功。
    (3) 观察mave仓库中增加的内容。
  2. idea中的maven设置:点击file菜单——>setting——>Build Execution Deployment ——>Build tools——>Maven——>Importing
    ——>勾选 Automatically Download:Source(自动下载源码)——>Ignored Files选中Ignored Files——>逐个查看剩余几个选项——>ok。
    注意:配置完毕后,一定要在idea中查看Maven的hone目、用户setting文件、本地仓库位置是否正确。
  3. 创建一个普通Maven项目,
    (1) 上面第6小节步骤中不选择maven-archetype-webapp模板,生成一个干净的Maven项目。
    (2) 目录结构:src有两个目录main和test,main下面的java存放源代码,test下绿色的java目录存测试代码;main下面的resource目录存放配置文件。
    (3) 点击idea右上角的到三角——>edit configuration——>选择Tomcat——>选择Deployment——>增加webapp应用入口——>application context不输入任何字符,则测试时输入http://localhost:8080/即可;若输入其它目录,则需在http://localhost:8080/目录;访问一个网站,需要指定一个文件夹的名字。
  4. 在idea中标记文件夹功能:
    (1) 选中某个目录,按鼠标右键——>Mark Directory as 几个选项,源码目录,测试源码目录等。
    (2) 点击File——>project structure——>Modules——>选中某个文件夹Mark as:Source、Test、Resource等文件夹类型。
    10.在idea中配置Tomcat:
    (1) 点击idea右上角的到三角——>edit configuration——>出现default——>点击+——>选择Tomcat的Local。
    (2) 一定要点击+,通过+来增加一个Tomcat的local,配置Tomcat的home目录,选择默认浏览器,选择JDK版本,选择Tomcat的默认端口,这样就能启动在Idea 中启动Tomcat。
    (3)如果不选择+,直接点击default,配置default下的Tomcat,即使配置完毕也不能再Idea中启动Tomcat服务。
  5. pom.xml文件:Maven的核心配置文件
    (1) jar包与war包(javaweb应用)
    (2) 由于Maven的约定大于配置,可能会导致我们自己写的配置文件无法被导出或生效;在build中配置resource,来防止我们资源导出失败问题
//在build中配置resources,来防止我们资源导出失败的问题,java源代码目录下的resource资源不做下列配置,则编译的输出文件target目录下不会导出这些资源文件。
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
  1. idea 设置虚拟路径和tomcat配置虚拟目录映射,解决在idea中配置好tomcat,启动服务无法程序入口。
    (1) 使用idea访问
    点击工具栏的运行配置Edit Configurations
    在弹出的Run/debug Configurations中选中tomcat容器,选择deployment这个tab
    选择好目录后,更改为自己指定的目录名称
    重启tomcat就可以访问了
    (2) 使用tomcat访问虚拟路径:在 tomcat的conf目录中的server.xml文件下配置,docBase是绝对路径,path是相对路径。
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
		<Context docBase="D:/development/gitdev/hjwulian/out/artifacts/hjwulian" 
		path="/hjwulian" 
		reloadable="true" 
		source="org.eclipse.jst.jee.server:hjwulian"/>
	</Host>
  1. 不能自动导入jar包的问题
//在新建的一个Maven项目,pom.xml文件中插入一下依赖包
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
//maven没有自动将相应的jar包导入。
//解决办法:FIle——>setting——>Build Execution Deployment ——>Build tools——>Maven——>Ignored Files勾选对应项目的pom.xml文件即可。
  1. idea生成web.xml文件中的webapp太老,用tomcat的web.xml内容替换
//idea自动生成web.xml内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

  <display-name>Archetype Created Web Application</display-name>
</web-app>
//tomcat的web.xml内容
<?xml version="1.0" encoding="UTF-8"?>
<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">
</web-app>
  1. Maven仓库的使用:https://mvnrepository.com/
  2. idea2.7.2与高版本的maven不兼容,只能配maven3.3.9

六、Servlet

  1. Servlet是sun公司开发动态web的一门技术;sun公司在api中提供一个叫Servlet接口。
  2. 开发servlet程序步骤:
    (1) 编写一个类,实现Servlet实现该接口;
    (2) 把开发好的java类部署在web服务器中;
    (3) 把实现Servlet接口的java程序叫做Servlet。
  3. 编写HelloServlet详细过程
    (1) 构建一个普通的Maven项目javaweb-02-servlet03,删除src目录;以后我们的学习就在这个项目里面建立module(module为子模块),这个空的工程就是Maven主工程,删除src目录。
    (2) 在这个父项目下加一个module子类HelloServlet,按Maven规范补齐java与resource目录并设置目录类型。
    (3) 关于maven父子工程的理解
//在父项目中有
    <modules>
        <module>servlet01</module>
    </modules>
 //子项目中有
     <parent>
        <artifactId>javaweb-02-servlet03</artifactId>
        <groupId>com.sxsl</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

(4) 父项目中的jar包子项目可以使用,而子项目中的jar包父项目不能使用。
(5) Maven环境优化: 修改web.xml为最新; 将Maven结构搭建完整。
(6) 编写一个Servlet类,实现Servlet接口,这里我们直接继承 HttpServlet。

package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class HelloServlet extends HttpServlet {
    //
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       PrintWriter writer= resp.getWriter();
       writer.print("Hello Servlet");
    }

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

(7) 编写Servlet映射:为什么要映射,因为我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接Web服务器,故我们需要在web服务器中注册我们写的Servlet,还需要给它一个浏览器访问的路径。

//web.xml增加以下内容
   <servlet>
       <servlet-name>hello</servlet-name>
       <servlet-class>com.sxsl.servlet.HelloServlet</servlet-class>
   </servlet>
  <servlet-mapping>
      <servlet-name>hello</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>

(8) 配置Tomcat:点击idea右上角的到三角——>edit configuration——>出现default——>点击+——>选择Tomcat的Local。在Deployment中选择war包,切输入访问入口路径application context=/s01。
(9) 测试,启动Tomcat,直接调用http://localhost:8080/s01/显示webapp目录下的静态网页index.html,输入http://localhost:8080/s01/hello调用com.sxsl.servlet.HelloServlet。
4. Servlet原理 servlet是有web服务器调用;web服务器收到浏览器请求后会:
在这里插入图片描述
5. Mapping问题:
(1) 一个Servlet对应一个路径;

  <servlet-mapping>
      <servlet-name>hello</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>

(2) 一个Servlet对应多个个路径;

  <servlet-mapping>
      <servlet-name>hello</servlet-name>
      <url-pattern>/hello</url-pattern>
  </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>

(3) 一个Servlet可以指定通配路径;

  <servlet-mapping>
      <servlet-name>hello</servlet-name>
      <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>

(4) 一个Servlet可以指定默认路径;

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>//*</url-pattern>
</servlet-mapping>

(5) 指定一些前缀或后缀;

    <!--可以自定义后缀实现请求映射,*前面不能加任何路径-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.lwp</url-pattern>
</servlet-mapping>

(6) 优先级:指定了固有路径的优先级最高,如果找不到就会走默认的处理。
6. ServletContext: web容器在启动时,它会为每个web程序都创建一个对应的ServletContext对象,它代表当前的web应用。
(1) 共享数据

//首先创建一个放置属性的类
package com.sxsl.servlet;

import javax.servlet.ServletContext;
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 HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String userName="lwp";
        context.setAttribute("userName",userName);//将一个数据保存在ServletContext中,名字为userName,值为lwp。

        System.out.printf("Hello");
    }

}
//其次则创建一个取属性值的类
package com.sxsl.servlet;

import javax.servlet.ServletContext;
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 GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        String userName=(String) context.getAttribute("userName");
        resp.getWriter().print("名字:"+userName);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
//在web.xml配置好Servlet的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
         
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.sxsl.servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>getc</servlet-name>
    <servlet-class>com.sxsl.servlet.GetServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>getc</servlet-name>
    <url-pattern>/getc</url-pattern>
  </servlet-mapping>
</web-app>
//最后想访问放置属性值的类再访问获取属性值的类

(2) 获取初始化参数

  <!--配制一些web应用初始化参数-->
  <context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
  </context-param>

  <servlet>
    <servlet-name>gp</servlet-name>
    <servlet-class>com.sxsl.servlet.ServletDemo03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gp</servlet-name>
    <url-pattern>/gp</url-pattern>
  </servlet-mapping>
package com.sxsl.servlet;

import javax.servlet.ServletContext;
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 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().print(url);

    }

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

(3) 请求转发

package com.sxsl.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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 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);//调用佛如Word办法请求转发
        context.getRequestDispatcher("/gp").forward(req,resp);
    }

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

(4) 读取资源文件:需要一个文件流
properties:在java目录下新建properties和在resource下新建properties均被打包到同一路径下,class目录,我们俗称为classpath。

//定义一个资源文件bb.properties,放在resource文件夹下
username=root
password=12334sdsddd
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
//在web.xml中增加映射
<servlet>
    <servlet-name>s5</servlet-name>
    <servlet-class>com.sxsl.servlet.ServletDemo05</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>s5</servlet-name>
    <url-pattern>/s5</url-pattern>
  </servlet-mapping>

重启测试即可。

七、 HttpServletResponse

  1. web服务器接到客服端的http请求,针对这个请求分别创建一个代表请求的HttpServletRequest对象和代表响应的HttpServletResponse对象。
  2. 要获取客户端请求过来的参数,找HttpServletRequest;给客户端响应一些信息找HttpServletResponse。
  3. 分类:
    (1) 负责向客户端(浏览器)发送数据的相关方法
getWriter()
getOutputStream()

(2) 负责向客户端(浏览器)发送响应头的相关方法

  resp.addDateHeader();
   resp.addHeader();
   resp.addIntHeader();
   resp.setDateHeader();
   resp.setHeader();
   resp.setIntHeader();

(3) 负责向客户端(浏览器)发送响应状态码的相关方法

resp.setStatus();

(4) 响应状态码的常量

SC_OK = 200;
SC_MULTIPLE_CHOICES = 300;
SC_BAD_REQUEST = 400;
SC_NOT_FOUND = 404;
SC_INTERNAL_SERVER_ERROR = 500;
  1. 常见应用
    (1) 向浏览器输出信息
    (2) 下载文件的步骤
    获取下载文件的路径及文件名
    想办法让浏览器支持下载我们需要的东西
    获取下载文件的输入流
    创建缓冲区
    获取OutputStream对象
    将FIleOutputStream流写入buffer缓冲区
    使用OutputStream将缓冲区的数据输出到客户端
//文件下载代码
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取下载文件的路径及文件名
        String realPath="C:\\Users\\Administrator\\IdeaProjects\\javaweb02servlet\\response\\target\\classes\\李维平.png";
        System.out.println("下载的文件路径:"+realPath);
        String fileName= realPath.substring( realPath.lastIndexOf( "\\" )+1 );
        System.out.println("下载的文件名称:"+fileName);
        //想办法让浏览器支持下载我们需要的东西,中文文件名用URLEncoder.encode(fileName,"utf-8") 
        resp.setHeader( "Content-disposition","attachment;filename="+URLEncoder.encode(fileName,"utf-8")  );
        //获取下载文件的输入流
        FileInputStream in=new FileInputStream( realPath );
        //创建缓冲区
        int len=0;
        byte[] buffer=new byte[2014];
        //获取OutputStream对象
        ServletOutputStream out=resp.getOutputStream();
        //将FIleOutputStream流写入buffer缓冲区,使用OutputStream将缓冲区的数据输出到客户端
        while ((len=in.read(buffer))>0){
            out.write( buffer,0,len );
        }
        in.close();
        out.close();
    }

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

//注册web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>com.sxsl.servlet.ImageServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/img</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>filedown</servlet-name>
    <servlet-class>com.sxsl.servlet.FileServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>filedown</servlet-name>
    <url-pattern>/down</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>RedirectServlet</servlet-name>
    <servlet-class>com.sxsl.servlet.RedirectServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>RedirectServlet</servlet-name>
    <url-pattern>/red</url-pattern>
  </servlet-mapping>
</web-app>
//response验证码代码
package com.sxsl.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器3秒刷新一次
        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/jpeg" );
        //网站存在缓存,不让浏览器缓存
        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" );

        }
        num=sb.toString()+num;
        return num;
    }

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

(3) 实现重定向:一个web资源收到客户端请求,它会通知客户端去访问另外一个资源,这个过程叫重定向。

resp.sendRedirect("/s5");

重定向与转发的区别:均能实现网页跳转;转发时url不会发生变化,重定向时URL地址栏发生变化。

package com.sxsl.servlet;

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 RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /* 原理
           resp.setHeader( "location","/sp/img" );
           resp.setStatus( HttpServletResponse.SC_MOVED_TEMPORARILY );
       */
        resp.sendRedirect( "/sp/img" );//重定向
    }

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

八、HttpServletRequest

  1. HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest中;通过HttpServletRequest的方法获得客服端的所有信息。
  2. 获取前端传递的参数并转发:
        req.getParameter(  ) ; //获取单个参数值
        req.getParameterValues(  ) ;//获取多个参数值
//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<h1>登录</h1>
<div style="align-content: center">
    <%--以post方式提交表单,提交到login请求中--%>
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username"> <br>
        密 码:<input type="password" name="password"> <br>
        爱 好:
        <input type="checkbox" name="hobbys" value="美女"> 美女
        <input type="checkbox" name="hobbys" value="代码"> 代码
        <input type="checkbox" name="hobbys" value="唱歌"> 唱歌
        <input type="checkbox" name="hobbys" value="电影"> 电影
        <br>
        <input type="submit">
    </form>

</div>

</body>
</html>

//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.sxsl.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
</web-app>

//LoginServlet.java
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;

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

        req.setCharacterEncoding( "utf-8" );
        resp.setCharacterEncoding( "utf-8" );

        String username=req.getParameter( "username" );
        String password=req.getParameter( "password" );
        String[] hobbys=req.getParameterValues( "hobbys" );
        System.out.println("=================");
        //后台接收中文乱码问题
        System.out.println(username);
        System.out.println(password);
        System.out.println( Arrays.toString(hobbys));
        System.out.println("=================");

        //通过请求转发
        //这里的 / 代表当前的web应用。
        req.getRequestDispatcher( "/success.jsp" ).forward( req,resp );

    }

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

//success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>登录成功!!</h1>
</body>
</html>

  1. ${pageContext.request.contextPath}它的作用是取出所部署项目的名字;web-app 的版本,如果低于2.4, ${pageContext.request.contextPath}不支持解析。

九、cookie与session

(一) cookie知识

  1. 会话:用户打开浏览器,点击了很多超链接,访问多个web资源,再关闭浏览器,这个过程叫会话。
  2. 保存会话的两种技术:
    (1) cookie:客户端技术(响应和请求)
    (2) session:服务器技术,利用该技术可以保存用户的会话信息。我们可以把信息或数据放在session中。
    (3) 常见应用场景:上次登录网站成功,下次不再登录,直接访问,免去登录过程。
  3. cookie:
    (1) 从请求中拿到cookie信息;
    (2) 服务端响应给客户端cookie。
Cookie[] cookies=req.getCookies();//获得cookie
cookie.getName();//获取cookie的key
cookie.getValue() ;//获取cookie的值
new Cookie( "lastLoginTime",System.currentTimeMillis()+"" );//创建一个新的cookie
cookie.setMaxAge( 24*60*60 );//设置cookie的有效期
resp.addCookie( cookie );//响应客户端一个cookie
  1. cookie一般保存在本地的用户目录下的appdata下:
    (1) 一个cookie只能保存一个信息;
    (2) 一个web站点可以给浏览器发送多个cookie,每个站点最多存放20个cookie;
    (3) cookie大小限制为4kb;
    (4) 300各cookie为浏览器上限。
  2. 删除cookie
    (1) 不设置有效期,关闭浏览器,cookie自动失效;
    (2) 设置有效期时间为0.
  3. 解决中文乱码,通过先编码再解码
Cookie cookie=new Cookie( "name", URLEncoder.encode( "李维平","utf-8" )); //编码
out.write( URLDecoder.decode( cookie.getValue(),"utf-8")); //解码
  1. 完整cookie代码
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

<display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>CookieDemo01</servlet-name>
        <servlet-class>com.sxsl.servlet.CookieDemo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieDemo01</servlet-name>
        <url-pattern>/c1</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>CookieDemo02</servlet-name>
        <servlet-class>com.sxsl.servlet.CookieDemo02</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieDemo02</servlet-name>
        <url-pattern>/c2</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>CookieDemo03</servlet-name>
        <servlet-class>com.sxsl.servlet.CookieDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieDemo03</servlet-name>
        <url-pattern>/c3</url-pattern>
    </servlet-mapping>

</web-app>

//CookieDemo01
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

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

        //解决中文乱码
        req.setCharacterEncoding( "utf-8" );
        resp.setCharacterEncoding( "utf-8" );
        PrintWriter out=resp.getWriter();

        //cookie,服务器端从客户端获取
        Cookie[] cookies=req.getCookies(); //这里返回数组,说明cookie返回多个值
        //判断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()+"" );
        //给cookie设置有效期为1天
        cookie.setMaxAge( 24*60*60 );
        resp.addCookie( cookie );

    }

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

//CookieDemo02
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

//删除cookie
public class CookieDemo02 extends HttpServlet {
    @Override
    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 );

    }

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

//CookieDemo03
package com.sxsl.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;

//中文数据传递
public class CookieDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //cookie,服务器端从客户端获取
        req.setCharacterEncoding( "utf-8" );
        resp.setCharacterEncoding( "utf-8" );

        Cookie[] cookies=req.getCookies(); //这里返回数组,说明cookie返回多个值
        PrintWriter out=resp.getWriter();
        //判断cookie是否存在
        if (cookies!=null){
            //如果存在怎么办
            out.write( "您上一次访问的时间是:" );

            for (int i=0; i<cookies.length; i++){
                Cookie cookie=cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals( "name" )){
//                  // 再解码
                    out.write( URLDecoder.decode( cookie.getValue(),"utf-8"));
                }
            }
        }else {
            out.write( "这是您第一次访问!!" );
        }
        //如果在实战中出现乱码,先编码
        Cookie cookie=new Cookie( "name", URLEncoder.encode( "李维平","utf-8" ));
        resp.addCookie( cookie );


    }

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

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>

  <groupId>com.sxsl</groupId>
  <artifactId>javaweb-session-cookie</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
    </dependency>
  </dependencies>
</project>

(二) session知识(重点)

  1. session定义:
    (1) 服务器会给每个用户(浏览器)创建一个session对象;
    (2) 一个session独占一个浏览器,只要浏览器没有关闭,这个session就一直存在;
    (3) 用户登录后,他就可以访问整个网站(授权范围内),如保存用户的信息或保存购物车的信息。
  2. session与cookie的区别:
    (1) cookie把用户的信息写到用户的浏览器,浏览器保存(可以保存多个);
    (2) session把用户的数据写到用户独占的session中,服务器端保存(只保存重要信息,减少服务器资源占用);
    (3) session对象由服务器创建。
  3. session使用场景
    (1) 保存一个登陆用户的信息;
    (2) 购物车信息;
    (3) 在网站中经常会使用的数据,我们将它保存在Session中。
  4. 使用session的代码
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>SessonDemo01</servlet-name>
    <servlet-class>com.sxsl.servlet.SessonDemo01</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessonDemo01</servlet-name>
    <url-pattern>/s1</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>SessonDemo02</servlet-name>
    <servlet-class>com.sxsl.servlet.SessonDemo02</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessonDemo02</servlet-name>
    <url-pattern>/s2</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>SessonDemo03</servlet-name>
    <servlet-class>com.sxsl.servlet.SessonDemo03</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessonDemo03</servlet-name>
    <url-pattern>/s3</url-pattern>
  </servlet-mapping>

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

//SessionDemo01
package com.sxsl.servlet;

import com.sxsl.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

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

        //得到session
        HttpSession session=req.getSession();
        //给session存东西
        session.setAttribute("name",new Person("李维平",18));
        //获取session的id
        String sessionId=session.getId();
        //判断session是否为新创建
        if(session.isNew()){
            resp.getWriter().write("session创建成功,Id为"+sessionId);
        }else{
            resp.getWriter().write("session已经在服务器中存在,Id为"+sessionId);
        }



    }

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

//SessionDemo02
package com.sxsl.servlet;

import com.sxsl.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessonDemo02 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        resp.setCharacterEncoding( "utf-8");
        req.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());

    }

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

//SessionDemo03
package com.sxsl.servlet;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session=req.getSession();
        //session.removeAttribute("name");
        session.invalidate();
    }

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

//Person
package com.sxsl.pojo;

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

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
    }

}

十、jsp

(一) jsp原理

  1. jsp:Java Server Page,java服务端页面,也和servlet一样,用于动态web技术。
    (1) 最大特点写jsp就像写HTML。
    (2) jsp与html的区别:HTML只给用户提供静态数据;jsp中可以嵌入java代码,为用户提供动态数据。
  2. 如何导入外部lib库:File——>Project Structure——>Libraries——>点击+——>选择JAVA——>选择java lib所在目录即可。
  3. jsp原理:浏览器向服务器发送请求,不管访问什么资源,其实都是访问servlet;jsp最终也会转化成一个java类,jsp本质上就是一个servlet。
    (1) jsp的三个主要函数
//初始化
   public void _jspInit() {
    }
//销毁
    public void jspDestroy() {
    }
//jspServicespService
 public abstract void _jspService(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException;

(2) 判断请求类别

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        return;
      }
    }

(3) 内置一些对象

    final javax.servlet.jsp.PageContext pageContext; //页面上下文
    javax.servlet.http.HttpSession session = null; 	 //session 对象
    final javax.servlet.ServletContext application;     //applicationContext
    final javax.servlet.ServletConfig config;				//config
    javax.servlet.jsp.JspWriter out = null;				    //out
    final java.lang.Object page = this;					   //page代表当前页面
    HttpServletRequest request								//请求
    HttpServletResponse response							//响应

(4) 输入页面前增加的代码

      response.setContentType("text/html;charset=UTF-8");  //设置响应页面的类型
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
//以上对象我们可以在JSP页面中随便使用

(5) 在jsp页面中,只要是java代码,原封不动的输出;如果是html则转化为out.write(“name”);out.write(“\r\n”);这样的格式输出到前端。

(二) Jsp基础语法及指令

  1. 任何语言都有自己的语法,java也有,jsp作为java技术的一种应用,它拥有自己一些扩充的语法,java所有的语法均支持。
    (1) 表达式:
    <%--jsp表达式
    作用:用来将程序的输出,输出到客户端
    <%=变量名或表达式%>
    --%>
    <%=new java.util.Date()%>

(2) jsp片段

   <%--jsp片段--%>
   <%
     int sum=0;
     for (int i = 1; i < 100; i++) {
         sum+=i;
     }
     out.println("<h1> sum="+sum+"</h1>");
   %>

(3) jsp声明:会被编译到jsp生成的类中,jsp表达式或片段会编译到_jspService方法中

    <%!
      static {
        System.out.println("loading servlet!!");
      }
      private  int globalvar=0;
      public void lwp(){
        System.out.println("进入了方法lwp");
      }
    %>

(4) jsp的注释不会再客户端的java文件中显示,html注释会生成在对应的java文件中。

(三) jsp指令

  1. jsp指令类型
指令描述
<%@ page … %>定义网页依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %>包含其他文件
<%@ taglib … %>引入标签库的定义
  1. Page指令:<%@ page attribute=“value” %>
属性描述
buffer指定out对象使用缓冲区的大小
autoFlush控制out对象的 缓存区
contentType指定当前JSP页面的MIME类型和字符编码
errorPage指定当JSP页面发生异常时需要转向的错误处理页面
isErrorPage指定当前页面是否可以作为另一个JSP页面的错误处理页面
extends指定servlet从哪一个类继承
import导入要使用的Java类
info定义JSP页面的描述信息
isThreadSafe指定对JSP页面的访问是否为线程安全
language定义JSP页面所用的脚本语言,默认是Java
session指定JSP页面是否使用session
isELIgnored指定是否执行EL表达式
isScriptingEnabled确定脚本元素能否被使用
  1. Include指令:JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
    <%@ include file=“文件相对 url 地址” %>
  2. Taglib指令:JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合;Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
    <%@ taglib uri=“uri” prefix=“prefixOfTag” %>
  3. 脚本
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--@ include是将两个页面合二为一--%>
    <%@ include file="/common/header.jsp"%>
    <h1>网页主体</h1>
    <%@ include file="/common/footer.jsp"%>
    <hr>
    <%--JSP标签
    jsp:include 拼接网页,本质上是3个网页
    --%>
    <jsp:include page="/common/header.jsp"/>
    <h1>网页主体</h1>
    <jsp:include page="/common/footer.jsp"/>
</body>
</html>

(四)、九大内置对象

  1. 9大具体对象内容
英文名称中文名称类型作用域
request请求对象类型 javax.servlet.ServletRequest作用域 Request
response响应对象类型 javax.servlet.SrvletResponse作用域 Page
pageContext页面上下文对象类型 javax.servlet.jsp.PageContext作用域 Page
session会话对象类型 javax.servlet.http.HttpSession作用域 Session
application (ServletContext)应用程序对象类型 javax.servlet.ServletContext作用域 Application
out输出对象类型 javax.servlet.jsp.JspWriter作用域 Page
config (ServletCOnfig)配置对象类型 javax.servlet.ServletConfig作用域 Page
page页面对象类型 javax.lang.Object作用域 Page
exception例外对象类型 javax.lang.Throwable作用域 page

(五)jsp标签、JSTL标签、EL表达式

  1. EL表达式${}:获取数据、执行运算、获取web开发的常用对象、调用java方法
操作符描述
.访问一个Bean属性或者一个映射条目
[]访问一个数组或者链表的元素
( )组织一个子表达式以改变优先级
  • |加
  • |减或负
  • |乘
    / or div| 除
    % or mod| 取模
    == or eq| 测试是否相等
    != or ne |测试是否不等
    < or lt |测试是否小于

or gt| 测试是否大于
<= or le| 测试是否小于等于
= or ge| 测试是否大于等于
&& or and| 测试逻辑与
|| or or |测试逻辑或
! or not| 测试取反
empty| 测试是否空值

  1. jsp标签:
//jsptag.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--jsp:include--%>
<h1>1</h1>
<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="lwp"></jsp:param>
    <jsp:param name="age" value="22"></jsp:param>
</jsp:forward>

</body>
</html>
//jsptag2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--jsp:include--%>
<h1>1</h1>
<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="lwp"></jsp:param>
    <jsp:param name="age" value="22"></jsp:param>
</jsp:forward>

</body>
</html>
  1. JSTL标签:它的使用就是为了弥补html标签的不足;它定义了许多标签供我们使用,标签的功能与java代码一样。
    (1) JSTL 库安装:
    从Apache的标准标签库中下载的二进包(jakarta-taglibs-standard-current.zip)。下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/下载jakarta-taglibs-standard-1.1.1.zip 包并解压,将jakarta-taglibs-standard-1.1.1/lib/下的两个jar文件:standard.jar和jstl.jar文件拷贝到/WEB-INF/lib/下和C:\Program Files\JetBrains\apache-tomcat-9.0.45-windows-x64\apache-tomcat-9.0.45\lib目录下(特别是后一个目录,否则报500错误)。
    (2) 核心标签
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
标签描述
<c:out>用于在JSP中显示数据,就像<%= … >
<c:set>用于保存数据
<c:remove>用于删除数据
<c:catch>用来处理产生错误的异常状况,并且将错误信息储存起来
<c:if>与我们在一般程序中用的if一样
<c:choose>本身只当做<c:when>和<c:otherwise>的父标签
<c:when> <c:choose>的子标签,用来判断条件是否成立
<c:otherwise> <c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行
<c:import>检索一个绝对或相对 URL,然后将其内容暴露给页面
<c:forEach>基础迭代标签,接受多种集合类型
<c:forTokens>根据指定的分隔符来分隔内容并迭代输出
<c:param>用来给包含或重定向的页面传递参数
<c:redirect>重定向至一个新的URL.
<c:url>使用可选的查询参数来创造一个URL
(3) 格式化标签
<%@ taglib prefix="fmt"   uri="http://java.sun.com/jsp/jstl/fmt" %>
标签描述
fmt:formatNumber使用指定的格式或精度格式化数字
fmt:parseNumber解析一个代表着数字,货币或百分比的字符串
fmt:formatDate使用指定的风格或模式格式化日期和时间
fmt:parseDate解析一个代表着日期或时间的字符串
fmt:bundle绑定资源
fmt:setLocale指定地区
fmt:setBundle绑定资源
fmt:timeZone指定时区
fmt:setTimeZone指定时区
fmt:message显示资源配置文件信息
fmt:requestEncoding设置request的字符编码
(3) SQL标签
<%@ taglib prefix="sql"  uri="http://java.sun.com/jsp/jstl/sql" %>
标签描述
sql:setDataSource指定数据源
sql:query运行SQL查询语句
sql:update运行SQL更新语句
sql:param将SQL语句中的参数设为指定值
sql:dateParam将SQL语句中的日期参数设为指定的java.util.Date 对象值
sql:transaction在共享数据库连接中提供嵌套的数据库行为元素,将所有语句以一个事务的形式来运行
(4) JSTL函数
<%@ taglib prefix="fn"   uri="http://java.sun.com/jsp/jstl/functions" %>
函数描述
fn:contains()测试输入的字符串是否包含指定的子串
fn:containsIgnoreCase()测试输入的字符串是否包含指定的子串,大小写不敏感
fn:endsWith()测试输入的字符串是否以指定的后缀结尾
fn:escapeXml()跳过可以作为XML标记的字符
fn:indexOf()返回指定字符串在输入字符串中出现的位置
fn:join()将数组中的元素合成一个字符串然后输出
fn:length()返回字符串长度
fn:replace()将输入字符串中指定的位置替换为指定的字符串然后返回
fn:split()将字符串用指定的分隔符分隔然后组成一个子字符串数组并返回
fn:startsWith()测试输入字符串是否以指定的前缀开始
fn:substring()返回字符串的子集
fn:substringAfter()返回字符串在指定子串之后的子集
fn:substringBefore()返回字符串在指定子串之前的子集
fn:toLowerCase()将字符串中的字符转为小写
fn:toUpperCase()将字符串中的字符转为大写
fn:trim()移除首位的空白符
(5) JSTL使用步骤:
引入对应的taglib;使用其中的方法;在tomcat中也要导入jstl的包,否则报JSTL解析错误。
//coreif.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h4>if测试</h4>
    <hr>
    <%--
        EL表达式获取表单的数据${param.参数名}
    --%>
    <form action="coreif.jsp" method="get">
        <input type="text" name="username" value="${param.username}">
        <input type="submit" value="登录">
    </form>
    <%--判断如果提交的用户名是admin则显示登录成功--%>
    <c:if test="${param.username=='admin'}" var="isAdmin">
        <c:out value="管理员欢迎你!!"/>
    </c:if>
    <C:out value="${isAdmin}"/>
</body>
</html>

//corewhen.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--定义一个变量score,值为85--%>
    <c:set var="score" value="85"/>
    <c:choose>
        <c:when test="${score>=90}">
            你的成绩为优秀!
        </c:when>
        <c:when test="${score>=80}">
            你的成绩为良好!
        </c:when>
        <c:when test="${score>=60}">
            你的成绩为及格!
        </c:when>
        <c:when test="${score>=60}">
            你的成绩为不及格!
        </c:when>

    </c:choose>
</body>
</html>

//croeforeach
<%@ page import="java.lang.reflect.Array" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        ArrayList<String > people= new ArrayList();
        people.add( 0,"张三" );
        people.add( 1,"李四" );
        people.add( 2,"王五" );
        people.add( 3,"赵六" );
        people.add( 4,"田七" );
        request.setAttribute( "list",people );
    %>
    <%--
        var,每次遍历出来的变量
        items,要遍历的对象
        begin,从哪儿开始
        end,到哪儿
        step,步长
    --%>
    <C:forEach var="people" items="${list}">
        <c:out value="${people}"/> <br>
    </C:forEach>
    <hr>
    <c:forEach var="people" items="${list}" begin="1" end="3" step="2">
        <c:out value="${people}"/> <br>
    </c:forEach>

</body>
</html>

十一:JavaBean

  1. JavaBean的格式:必须有一个无参构造函数;属性必须私有化;必须有对应的get/set方法
  2. 一般用来与数据库中表的字段做映射;ORM,对象关系映射
    表——>类,字段——>属性,行——>对象
  3. JavaBean 属性
方法描述
getPropertyName()举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 getMyName() 来读取这个属性。这个方法也称为访问器。
setPropertyName()举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 setMyName()来写入这个属性。这个方法也称为写入器。
  1. 访问JavaBean
    jsp:useBean 标签可以在 JSP 中声明一个 JavaBean,然后使用。声明后,JavaBean 对象就成了脚本变量,可以通过脚本元素或其他自定义标签来访问。jsp:useBean 标签的语法格式如下:
<jsp:useBean id="bean 的名字" scope="bean 的作用域" typeSpec/>

<jsp:useBean id="id" class="bean 编译的类" scope="bean 作用域">
   <jsp:setProperty name="bean 的 id" property="属性名"  
                    value="value"/>
   <jsp:getProperty name="bean 的 id" property="属性名"/>
   ...........
</jsp:useBean>
  1. 代码:
//People.java
package com.sxsl.pojo;
//实体类一般与数据库中的表结构一一对应
public class People {
   private int id;
   private String name;
   private int age;
   private String addre;

   public People() {

   }

   public People(int id, String name, int age, String addre) {
       this.id = id;
       this.name = name;
       this.age = age;
       this.addre = addre;
   }

   public int getId() {
       return id;
   }

   public void setId(int id) {
       this.id = id;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public String getAddre() {
       return addre;
   }

   public void setAddre(String addre) {
       this.addre = addre;
   }

   @Override
   public String toString() {
       return "People{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", age=" + age +
               ", addre='" + addre + '\'' +
               '}';
   }
}

//javabean.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
   <jsp:useBean id="people" class="com.sxsl.pojo.People" scope="page"/>
   <jsp:setProperty name="people" property="addre" value="西安"/>
   <jsp:setProperty name="people" property="id" value="3"/>
   <jsp:setProperty name="people" property="name" value="王五"/>
   <jsp:setProperty name="people" property="age" value="25"/>
   ID:<jsp:getProperty name="people" property="id"/>    <br>
   姓名:<jsp:getProperty name="people" property="name"/> <br>
   年龄:<jsp:getProperty name="people" property="age"/> <br>
   地址:<jsp:getProperty name="people" property="addre"/> <br>

</body>
</html>

十二:MVC三层架构

  1. mvc:Model、view、Controller,模型、视图、控制器
  2. MVC模型简介
    (1) Model:业务处理:业务逻辑(service);数据持久层:CRUD(DAO)。
    (2) View :展示数据,提供链接发起servlet请求(a、form、img。。。)。
    (3) Controller(servlet):接受用户的请求(request、session、…);交给业务层处理对应代码;控制视图的跳转。
  3. 登录过程:登录—>接受用户的登录请求—>处理用户的请求(获取用户登录的参数,username,password…)—>交给业务层处理登录业务(判断用户名和密码是否正确:事务)—>DAO层查询用户名和密码是否正确—>数据库。

十三:Filter

  1. Servlet和JSP中的过滤器都是Java类,它们存在的目的如下:在请求访问后端资源时拦截它;管理从服务器返回给客户端的响应。
  2. 实现过滤器的步骤
    (1) 导包,千万别盗错了javax.servlet.filter;
    (2) 编写过滤器,实现filter接口,重写三个方法
    (3) 在web.xml中配置filter。
  3. 完整代码
//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>

    <groupId>com.sxsl</groupId>
    <artifactId>javaweb-filter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun/jstl -->
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/taglibs/standard -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

    </dependencies>
</project>

//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>ShowServlet</servlet-name>
        <servlet-class>com.sxsl.sersvlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/show</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.sxsl.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--只要是servlet下的任何请求都会经过这个过滤器-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
</web-app>

//CharacterEncodingFilter.java
package com.sxsl.filter;

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

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

    //chain:链
    /*
    1、过滤器中所有代码,在过滤特定请求时都会执行
    2、必须要让过滤器继续通行
       chain.doFilter(request,response);
    */
    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执行后。。。");
    }

    //销毁,服务器关闭时才销毁
    public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");
    }
}

//ShowServlet.java
package com.sxsl.sersvlet;

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 ShowServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("你好,世界!");
    }

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

十四 监听器

  1. 定义:监听器是Servlet规范中定义的一种特殊类,用于监听ServletContext、HttpSession和ServletRequest等域对象的创建和销毁事件,它还可以监听域对象的属性发生修改的事件,可以在事件发生前或者发生后做一些必要的处理。
  2. 实现监听器的步骤:编写监听程序,实现监听类别的接口,重写方法;在web.xml中注册监听程序;测试功能
  3. 详细代码
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>ShowServlet</servlet-name>
        <servlet-class>com.sxsl.servlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/show</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.sxsl.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--只要是servlet下的任何请求都会经过这个过滤器-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

    <!--注册监听器-->
    <listener>
        <listener-class>com.sxsl.listener.OnlineCountListener</listener-class>
    </listener>
    //设置session自动销毁时间间隔
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>

//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <h1>当前有 <span style="color: blue"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>  人在线</h1>
  </body>
</html>

//OnlineCountListener.java
package com.sxsl.listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//统计网站在线人数:统计sessions
public class OnlineCountListener implements HttpSessionListener {
    //创建sesson监听:看你的一举一动
    //一旦创建一个session就会触发这个事件
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx= se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount=(Integer)ctx.getAttribute( "OnlineCount" );
        if(onlineCount==null){
            onlineCount=new Integer( 1 );
        }else{
            int count =onlineCount.intValue();
            onlineCount=new Integer( count+1 );
        }
        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-1 );
        }
        ctx.setAttribute( "OnlineCount",onlineCount);

    }

    /*
      session销毁
      1、手动销毁 :se.getSession().invalidate();
      2、自动销毁
          <session-config>
             <session-timeout>1</session-timeout>
          </session-config>
    */
}

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>

    <groupId>com.sxsl</groupId>
    <artifactId>javaweb-filter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun/jstl -->
        <dependency>
            <groupId>com.sun</groupId>
            <artifactId>jstl</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/taglibs/standard -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

    </dependencies>
</project>

//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <h1>当前有 <span style="color: blue"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>  人在线</h1>
  </body>
</html>
  1. 一个用户登录界面是否成功的过滤
    (1)用户登录后,向session中放入用户的数据
    (2) 进入主页时判断该用户是否登录,要求在过滤器中实现。
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>ShowServlet</servlet-name>
        <servlet-class>com.sxsl.servlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/servlet/show</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ShowServlet</servlet-name>
        <url-pattern>/show</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.sxsl.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/servlet/login</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.sxsl.servlet.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/servlet/logout</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.sxsl.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>

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

    <!--注册监听器-->
    <listener>
        <listener-class>com.sxsl.listener.OnlineCountListener</listener-class>
    </listener>
    //设置session自动销毁时间间隔
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>

//success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>主页</h1>
    <p><a href="/servlet/logout">注销</a></p>
</body>
</html>

//SysFilter .java
package com.sxsl.filter;

import com.sxsl.util.Constant;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.LogRecord;

public class SysFilter implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request1= (HttpServletRequest) servletRequest;
        HttpServletResponse response1= (HttpServletResponse) servletResponse;

        if(request1.getSession().getAttribute( Constant.USER_SESSION )==null){
            response1.sendRedirect( "/error.jsp" );
        }
        filterChain.doFilter( servletRequest,servletResponse );
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void destroy() {

    }
}

//index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <h1>当前有 <span style="color: blue"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>  人在线</h1>
  </body>
</html>

//LogoutServlet.java
package com.sxsl.servlet;

import com.sxsl.util.Constant;
import org.omg.CORBA.Object;

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 LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        java.lang.Object user_session = req.getSession().getAttribute( Constant.USER_SESSION );
        if(user_session!=null){
            req.getSession().removeAttribute( Constant.USER_SESSION );
            resp.sendRedirect( "/login.jsp" );
        }else{
            resp.sendRedirect( "/login.jsp" );
        }
    }

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

//login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>登录</h1>
    <form action="servlet/login" method="post">
        <input type="text" name="username">
        <input type="submit" >
    </form>
</body>
</html>

//LoginServlet.java
package com.sxsl.servlet;

import com.sxsl.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 {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost( req, resp );
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端请求的参数
        String username=req.getParameter( "username" );
        if(username.equals( "admin" )){//登录成功
            req.getSession().setAttribute( Constant.USER_SESSION,req.getSession().getId());
            resp.sendRedirect( "/sys/success.jsp" );
        }else{//登录失败
            resp.sendRedirect( "/error.jsp" );
        }
    }
}

//error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>错误</h1>
    <h3>没有权限或用户名错误</h3>
    <a href="/login.jsp">返回主页</a>
</body>
</html>

//Constant.java
package com.sxsl.util;

public class Constant {
    public final static String USER_SESSION="USER_SESSION";
}

十五、JDBC

SMBMS项目

(一).准备工作

  1. 基本架构
    在这里插入图片描述

  2. 在数据库中创建对应的表、对应数据库代码如下:

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);
  1. 项目搭建
    (1)搭建一个maven web项目

(2)配置Tomcat并测试运行

(3)导入jar包;//pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>

  <groupId>com.sxsl</groupId>
  <artifactId>smbms</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.9</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.11</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>4.2.2.RELEASE</version>
    </dependency>
  </dependencies>
</project>

(4) 创建项目包结构

在这里插入图片描述

(5)编写实体类

//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;
   }
}

(6)编写基础公共类

1.数据库配置文件

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

2.编写数据库的公共类
在dao包建立BaseDao类

  //操作数据库的公共类
     public class BaseDao {     
         private static String driver;
         private static String url;
         private static String username;
         private static String password;
     
         //静态代码块,类加载的时候就初始化了
         static {
             Properties properties = new Properties();
             //通过类加载器读取对应的资源
             InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.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);
             } catch (Exception e) {
                 e.printStackTrace();
             }
             return connection;
         }
     
         //编写查询公共方法
         public static ResultSet execute(Connection connection,String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement) throws SQLException {
             //预编译的sql,在后面直接执行就可以了
             preparedStatement = connection.prepareStatement(sql);
     
             for (int i = 0; i < params.length; i++) {
                 //setObject,占位符从1开始,但是我们的数组是从0开始!
                 preparedStatement.setObject(i+1,params[i]);
             }
     
             resultSet = preparedStatement.executeQuery();
             return resultSet;
         }
     
     
         //编写增删改公共方法
         public static int execute(Connection connection,String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException {
             preparedStatement = connection.prepareStatement(sql);
     
             for (int i = 0; i < params.length; i++) {
                 //setObject,占位符从1开始,但是我们的数组是从0开始!
                 preparedStatement.setObject(i+1,params[i]);
             }
     
             int updateRows = preparedStatement.executeUpdate();
             return updateRows;
         }
     
     
         //释放资源
         public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
             boolean flag = true;
     
             if (resultSet!=null){
                 try {
                     resultSet.close();
                     //GC回收
                     resultSet = null;
                 } catch (SQLException e) {
                     e.printStackTrace();
                     flag = false;
                 }
             }
     
             if (preparedStatement!=null){
                 try {
                     preparedStatement.close();
                     //GC回收
                     preparedStatement = null;
                 } catch (SQLException e) {
                     e.printStackTrace();
                     flag = false;
                 }
             }
     
             if (connection!=null){
                 try {
                     connection.close();
                     //GC回收
                     connection = null;
                 } catch (SQLException e) {
                     e.printStackTrace();
                     flag = false;
                 }
             }
             return flag;
         }
     }

3.编写字符编码过滤器

//在filter中建立CharacterEncodingFilter类

public class CharacterEncodingFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        chain.doFilter(request,response);
    }
    public void destroy() {

    }
}

//在web.xml中注册

<!--字符编码过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.kuang.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

(7)导入静态资源

(二).登录注销实现

  1. 登录
    (1)编写前端代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>系统登录 - 超市订单管理系统</title>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/style.css" />
    <script type="text/javascript">
    </script>
</head>
<body class="login_bg">
    <section class="loginBox">
        <header class="loginHeader">
            <h1>超市订单管理系统</h1>
        </header>
        <section class="loginCont">
	        <form class="loginForm" action="${pageContext.request.contextPath }/login.do"  name="actionForm" id="actionForm"  method="post" >
				<div class="info">${error}</div>
				<div class="inputbox">
                    <label>用户名:</label>
					<input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/>
				</div>	
				<div class="inputbox">
                    <label>密码:</label>
                    <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/>
                </div>	
				<div class="subBtn">
					
                    <input type="submit" value="登录"/>
                    <input type="reset" value="重置"/>
                </div>	
			</form>
        </section>
    </section>
</body>
</html>

(2)将前端页面设置为首页
在web-inf中的web.xml加入以下代码即可实现设置首页功能

   <!--设置首页-->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

(3)编写dao层用户登录的接口UserDao
在dao中建立一个user包,在包中建一个UserDao接口,在接口中写

public User getLoginUser(Connection connection,String userCode,String userPassword) throws SQLException;

(4)编写UserDao接口的实现类UserDaoImpl

public class UserDaoImpl implements UserDao {
    //得到要登录的用户
    public User getLoginUser(Connection connection, String userCode,String userPassword) 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};
           //System.out.println(userPassword);
            rs = BaseDao.execute(connection, pstm, rs, sql, params);
            if (rs.next()){
                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);
           if (!user.getUserPassword().equals(userPassword))
              user=null;
        }
        return user;
    }
}

(4)编写业务层接口
在service下建立user包,建立UserService接口

public interface UserService {
    //用户登录
    public User login(String userCode,String password);
}

(5)编写业务层接口的实现类

//在service的user包中建立UserServiceImpl类

public class UserServiceImpl implements UserService {

    //业务层都会调用dao层,所以我们要引入Dao层;
    private UserDao userDao;
    public UserServiceImpl(){
        userDao = new UserDaoImpl();
    }


    public User login(String userCode, String password) {
        Connection connection = null;
        User user = null;

        try {
            connection = BaseDao.getConnection();
            //通过业务层调用对应的具体的数据库操作
            user = userDao.getLoginUser(connection, userCode,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            BaseDao.closeResource(connection,null,null);
        }
        return user;
    }

}

(6)编写Servlet类
在Servlet包中创建user包,在user包中建立LoginServlet类

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");
        //和数据库中的密码进行对比,调用业务层;
        UserService userService = new UserServiceImpl();
        User user = userService.login(userCode, userPassword);  //这里已经把登录的人给查出来了
        System.out.println(userCode);
        System.out.println(userPassword);
        if (user!=null){ //查有此人,可以登录
            //将用户的信息放到Session中;
            req.getSession().setAttribute(Constants.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);
    }
}

在web.xml中注册

<servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.kuang.servlet.user.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login.do</url-pattern>
</servlet-mapping>
  1. 注销
    在Servlet包的user包中建立LogoutServlett类
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户的Constants.USER_SESSION
        req.getSession().removeAttribute(Constants.USER_SESSION);
        resp.sendRedirect("/login.jsp");//返回登录页面
    }

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

在web.xml中注册

    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.kuang.servlet.user.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/jsp/logout.do</url-pattern>
    </servlet-mapping>

设置自动注销
设置30分后session自动失效

<session-config>
   <session-timeout>30</session-timeout>
</session-config>
  1. 登录拦截
    在filter中建立SysFilter类
public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    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(Constants.USER_SESSION);

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

    public void destroy() {

    }
}

在web.xml中注册

<!--用户登录过滤器-->
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.kuang.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/jsp/*</url-pattern>
    </filter-mapping>

(三).密码修改的实现

  1. 编写dao层用户修改密码的接口UserDao
    UserDao接口写如下代码
//修改当前用户密码
public int updatePwd(Connection connection, int id, String password) throws SQLException;
  1. 编写UserDao 接口实现类UserDaoImpl
 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, sql, params, pstm);
            BaseDao.closeResource(null,pstm,null);
        }

        return execute;
    }

  1. 编写业务层接口
    在service的user包中的UserService接口中添加如下代码
//根据用户ID修改密码
public boolean updatePwd(int id, String pwd);
  1. 编写业务层接口实现类
    在service的user包中的UserServiceImpl类中添加以下代码
public boolean updatePwd(int id, String pwd) {
        Connection connection = null;
        boolean flag = false;
        //修改密码
        try {
            connection = BaseDao.getConnection();
            if (userDao.updatePwd(connection,id,pwd)>0){
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            BaseDao.closeResource(connection,null,null);
        }
        return flag;
    }
  1. 编写Servlet类
    在Servlet包中的user包中建立UserServlet类
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method.equals("savepwd")&&method!=null){
            this.updatePwd(req,resp);
        }else if (method.equals("pwdmodify")){
            this.pwdModify(req, resp);
        }
    }

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

    //修改密码
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
        //从Session里面拿ID;
        Object o = req.getSession().getAttribute(Constants.USER_SESSION);

        String newpassword = req.getParameter("newpassword");

        System.out.println("UserServlet:"+newpassword);

        boolean flag = false;

        System.out.println(o!=null);
        System.out.println(StringUtils.isNullOrEmpty(newpassword));

        if (o!=null && newpassword!=null){
            UserService userService = new UserServiceImpl();
            flag = userService.updatePwd(((User) o).getId(), newpassword);
            if (flag){
                req.setAttribute("message","修改密码成功,请退出,使用新密码登录");
                //密码修改成功,移除当前Session
                req.getSession().removeAttribute(Constants.USER_SESSION);
            }else {
                req.setAttribute("message","密码修改失败");
                //密码修改成功,移除当前Session
            }
        }else {
            req.setAttribute("message","新密码有问题");
        }

        try {
            req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //验证旧密码,session中有用户的密码
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
        //从Session里面拿ID;

        Object o = req.getSession().getAttribute(Constants.USER_SESSION);
        String oldpassword = req.getParameter("oldpassword");
        System.out.println(oldpassword);
        //万能的Map : 结果集
        Map<String, String> resultMap = new HashMap<String,String>();

        if (o==null){ //Session失效了,session过期了
            resultMap.put("result","sessionerror");
        }else if (StringUtils.isNullOrEmpty(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");
            }
        }


        try {
            resp.setContentType("application/json");
            PrintWriter writer = resp.getWriter();
            //JSONArray 阿里巴巴的JSON工具类, 转换格式
            /*
            resultMap = ["result","sessionerror","result","error"]
            Json格式 = {key:value}
             */
            writer.write(JSONArray.toJSONString(resultMap));
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

在web.xml中注册

    <servlet>
        <servlet-name>updatePwd</servlet-name>
        <servlet-class>com.kuang.servlet.user.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>updatePwd</servlet-name>
        <url-pattern>/jsp/user.do</url-pattern>
    </servlet-mapping>

(四).用户管理实现

  1. 获取用户数量
    (1)编写查询总人数的接口UserDao
    UserDao接口写如下代码
//查询用户总数
public int getUserCount(Connection connection,String username ,int userRole)throws SQLException;

(2)UserDao接口实现类UserDaoImpl
向实现类中添加以下代码

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

        PreparedStatement pstm = null;
        ResultSet rs = null;
        int count = 0;

        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()); //输出最后完整的SQL语句


            rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);

            if (rs.next()){
                count = rs.getInt("count"); //从结果集中获取最终的数量
            }
            BaseDao.closeResource(null,pstm,rs);
        }
        return count;
    }

(3)编写业务层接口
在service的user包中的UserService接口中添加如下代码

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

(4)编写业务层接口实现类
在service的user包中的UserServiceImpl类中添加以下代码

public int getUserCount(String username, int userRole) {
            Connection connection = null;
            int count = 0;
            try {
                connection = BaseDao.getConnection();
                count = userDao.getUserCount(connection, username, userRole);
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                BaseDao.closeResource(connection,null,null);
            }

            return count;
        }
  1. 获取用户列表
    (1)编写UserDao
    UserDao接口写如下代码
//通过条件查询-userList
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)throws Exception;

(2)UserDao接口实现类UserDaoImpl
向实现类中添加以下代码

 public List<User> getUserList(Connection connection, String userName,int userRole,int currentPageNo, int pageSize)
            throws Exception {
        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);
            }
            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)编写业务层接口
在service的user包中的UserService接口中添加如下代码

 //根据条件查询用户列表
    public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);

(4)编写业务层接口实现类
在service的user包中的UserServiceImpl类中添加以下代码

 public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
        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) {
            e.printStackTrace();
        }finally{
            BaseDao.closeResource(connection, null, null);
        }
        return userList;
    }

3.获取角色操作
(1)编写接口RoleDao

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

(2)RoleDao接口实现类RoleDaoImpl
向实现类中添加以下代码

public class RoleDaoImpl implements RoleDao {
    //获取角色列表
    public List<Role> getRoleList(Connection connection) throws SQLException {

        PreparedStatement pstm = null;
        ResultSet resultSet = null;
        ArrayList<Role> roleList = new ArrayList<Role>();

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

            while (resultSet.next()){
                Role _role = new Role();
                _role.setId(resultSet.getInt("id"));
                _role.setRoleCode(resultSet.getString("roleCode"));
                _role.setRoleName(resultSet.getString("roleName"));
                roleList.add(_role);
            }
            BaseDao.closeResource(null,pstm,resultSet);
        }
        return roleList;
    }
}

(3)编写业务层接口
在service建立role包,然后建立RoleService接口,添加如下代码

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

(4)编写业务层接口实现类
在service的role包中的RoleServiceImpl类中添加以下代码

public class RoleServiceImpl implements RoleService {

    //引入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 e) {
            e.printStackTrace();
        } finally {
            BaseDao.closeResource(connection,null,null);
        }
        return roleList;
    }
}

4.编写Servlet类
对Servlet包中的user包中UserServlet类进行如下添加

//添加一个if判断
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method.equals("savepwd")&&method!=null){
            this.updatePwd(req,resp);
        }else if (method.equals("pwdmodify")&&method!=null){
            this.pwdModify(req, resp);
        }else if (method.equals("query")&&method!=null){
            this.query(req, resp);

        }
    }

    //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();
        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();
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值