最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

JavaWeb学习笔记

来源:博客园

1、JavaWeb

1.1、前言

  • Web:网页
  • 静态Web:
    • html,css
    • 提供给所有人看的数据始终不会改变
  • 动态Web:
    • 提供给别人看的数据会发生改变
    • 技术栈:Servlet/JSP、ASP、PHP在java中,动态Web资源开发的技术统称为javaweb;

1.2、Web应用程序

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


(资料图片仅供参考)

  • html.....这些资源可以被外界访问,可以对外界提供访问
  • URL
  • 这些统一的外部资源会被统一放在一个文件夹、wab应用程序-->Tomcat服务器
  • 一个Web应用又多部分组成(静态web和动态web)
    • html、css、js
    • jsp、servlet
    • java程序
    • jar包
    • 配置文件Web程序编写完成之后,若想给外界访问,需要一个服务器统一管理

1.3、静态Web

  • html、htm,这些都是网页后缀,如果服务器上一直存在这些东西,我们可以直接获取、联络
  • 静态Web存在的缺点:
    • Web页面无法更新,所有用户看到的都是同一个页面
      • 轮播图,点击特效
      • js
    • 无法和数据交互(数据无法持久化,用户无法交互)

1.4、动态Web

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

  • 缺点: 加入服务器的动态资源出现了错误,我们需要重新编写过我们的后台程序(停机维护)
  • 优点:
    • Web可以动态更新
    • 可以与数据库交互(数据持久化)

2、Web服务器

2.1、技术讲解

ASP:微软,国内最早流行的

  • 逻辑代码和页面混杂在一起
  • 维护成本高
  • 代码混乱PHP:
  • 开发速度快,功能强大,跨平台,代码简单
  • 无法存在大访问量的情况JSP/Servlet:B/S:浏览器和服务器C/S:客户端和浏览器
  • sun公司主推的B/S架构
  • 基于java语言的(所有的大公司,开源的的组件,都是java开发)
  • 可承载三高问题带来的影响(高并发、高可用、高性能)

2.2、Web服务器

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

  • IIS
    • 微软,ASP
    • windows自带的服务器
  • Tomcat
    • Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目
    • Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。
    • 对于一个初学Web的人来说,是最好的服务器

3、Tomcat

3.1、关于Tomcat

安装:官网安装,解压work文件夹:jsp,tomcat的工作原理是当浏览器访问某个jsp页面时,tomcat会在work目录里把这个jsp页面转换成.java文件,比如将index.jsp转换为index_jsp.java文件,而后编译为index_jsp.class文件,最后tomcat容器通过ClassLoader类把这个index_jsp.class类装载入内存,进行响应客户端的工作。tomcat会定时稍描容器内的jsp文件,读取每个文件的属性,当发现某个jsp文件发生改变时(文件的最后修改时间与上次稍描时不相同时),tomcat会重新转换、编译这个jsp文件。但是tomcat的稍描是定时的不是实时的,这也正是为什么jsp文件修改后需要几分钟的时间来等修改过的jsp生效。当然为了即刻生效,很多老前辈都会建议在修改jsp页面后立即清除work目录里的文件。

3.2、如何发布网站

3.3、网站该有的结构

4、Http

4.1、什么是http?

HTTP(超文本传输协议)是一种简单的传输协议,通常运行在TCP上

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

HTTPS:加密

  • 默认端口443

4.2、两个时代

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

4.3、Http请求

  • 客户端--发请求--服务器

常规

Request URL:https://www.baidu.com/   请求地址    Request Method:GET   请求方法    Status Code:200 OK   状态码    Remote(远程) Address:36.152.44.96:443   IP端口号

请求头

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,ja;q=0.5Cache-Control: max-age=0Connection: keep-aliveCookie: Host: www.baidu.comReferer: https://cn.bing.com/sec-ch-ua: " Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: cross-siteSec-Fetch-User: ?1Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77

1、请求行

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

2、消息头

//告诉服务器,支持哪种类型Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9//支持哪种编码格式Accept-Encoding: gzip, deflate, br//告诉服务器浏览器的语言环境Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,ja;q=0.5//缓存控制Cache-Control: max-age=0//告诉浏览器,请求完成是断开还是保持连接Connection: keep-alive//主机Host:

4.3、Http响应

  • 服务器--响应--客户端

百度响应头

Bdpagetype: 2Bdqid: 0xff178ac000047df4Cache-Control: privateConnection: keep-aliveContent-Encoding: gzipContent-Type: text/html;charset=utf-8Date: Mon, 01 Aug 2022 04:55:41 GMTExpires: Mon, 01 Aug 2022 04:55:41 GMTServer: BWS/1.1Set-Cookie: BDSVRTM=382; path=/Set-Cookie: BD_HOME=1; path=/Set-Cookie: H_PS_PSSID=36551_36463_36724_36413_36955_36948_36165_36917_36776_36745_26350_36938; path=/; domain=.baidu.comStrict-Transport-Security: max-age=172800Traceid: 1659329741065239809018381312961374617076Transfer-Encoding: chunkedX-Frame-Options: sameoriginX-Ua-Compatible: IE=Edge,chrome=1

请求响应码

  • 信息响应(100–199)
  • 成功响应(200–299)
  • 重定向(300–399)
  • 客户端错误(400–499)
  • 服务器错误 (500–599)

1**信息,服务器收到请求,需要请求者继续执行操作2**成功,操作被成功接收并处理3**重定向,需要进一步的操作以完成请求4**客户端错误,请求包含语法错误或无法完成请求5**服务器错误,服务器在处理请求的过程中发生了错误

5、maven

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

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

maven诞生

5.1、Maven架构管理工具

我们目前就是用来导入jar包Maven的核心思想:约定大于配置

  • 有约束,不要去违反Maven会规定如何去写java代码,必须按照这个规范来

5.2、安装Maven

1、下载:https://maven.apache.org/2、安装:解压即可3、配置环境变量

5.3、修改配置文件

配置阿里云镜像

5.4、本地仓库

配置本地仓库

5.5、创建Maven项目

5.6、创建一个干净的maven项目

给项目添加web配置,作为web目录

5.7、配置tomcat

6、Servlet

6.1、Servlet简介

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

6.2、构建一个普通的mave项目

6.3、构件父子工程

把src目录删掉后,再创建一个字工程这个父模块pom里面没有多余的东西,子模块需要用到的依赖可以直接从父模块获取父模块中的依赖子模块也可以使用

6.4、关于web.xml

6.5、ServletContext

ServletContext就是多个servlet类共享数据

1、共享数据

在这个文件中保存的name

public class Servlet_set extends HttpServlet {      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          ServletContext servletContext = this.getServletContext();          String name = "钟海华";          servletContext.setAttribute("name",name);      }        @Override      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          doGet(req, resp);      }  }

在另外一个文件中去访问:

public class Servlet_get extends HttpServlet {      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          resp.setCharacterEncoding("utf-8");          resp.setContentType("text/html");          ServletContext servletContext = this.getServletContext();          PrintWriter writer = resp.getWriter();          writer.print("名字:"+servletContext.getAttribute("name"));      }        @Override      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          doGet(req, resp);      }  }

对应的是两个不同的servlet

2、获取初始化参数

3、转发请求

//转发请求  setservletContext.getRequestDispatcher("/get").forward(req,resp);getServletContext servletContext = this.getServletContext();  PrintWriter writer = resp.getWriter();  writer.print("url:"+servletContext.getInitParameter("url"));

请求set,但是到get执行了代码

4、读取文件

6.6、HttpServletResponse

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

  • 如果想要获取客户端请求过来的参数,找HttpServletRequest对象
  • 如果想要给客户端回应信息,找HttpServletResponse对象

1、简单分类

  • 负责相浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;PrintWriter getWriter() throws IOException;
  • 负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);    void setContentLength(int var1);    void setContentLengthLong(long var1);    void setContentType(String var1);    void setBufferSize(int var1);void setDateHeader(String var1, long var2);    void addDateHeader(String var1, long var2);    void setHeader(String var1, String var2);    void addHeader(String var1, String var2);    void setIntHeader(String var1, int var2);    void addIntHeader(String var1, int var2);    void setStatus(int var1);
  • 响应状态码
int SC_CONTINUE = 100;  int SC_SWITCHING_PROTOCOLS = 101;  int SC_OK = 200;  int SC_CREATED = 201;  int SC_ACCEPTED = 202;  int SC_NON_AUTHORITATIVE_INFORMATION = 203;  int SC_NO_CONTENT = 204;  int SC_RESET_CONTENT = 205;  int SC_PARTIAL_CONTENT = 206;  int SC_MULTIPLE_CHOICES = 300;  int SC_MOVED_PERMANENTLY = 301;  int SC_MOVED_TEMPORARILY = 302;  int SC_FOUND = 302;  int SC_SEE_OTHER = 303;  int SC_NOT_MODIFIED = 304;  int SC_USE_PROXY = 305;  int SC_TEMPORARY_REDIRECT = 307;  int SC_BAD_REQUEST = 400;  int SC_UNAUTHORIZED = 401;  int SC_PAYMENT_REQUIRED = 402;  int SC_FORBIDDEN = 403;  int SC_NOT_FOUND = 404;  int SC_METHOD_NOT_ALLOWED = 405;  int SC_NOT_ACCEPTABLE = 406;  int SC_PROXY_AUTHENTICATION_REQUIRED = 407;  int SC_REQUEST_TIMEOUT = 408;  int SC_CONFLICT = 409;  int SC_GONE = 410;  int SC_LENGTH_REQUIRED = 411;  int SC_PRECONDITION_FAILED = 412;  int SC_REQUEST_ENTITY_TOO_LARGE = 413;  int SC_REQUEST_URI_TOO_LONG = 414;  int SC_UNSUPPORTED_MEDIA_TYPE = 415;  int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;  int SC_EXPECTATION_FAILED = 417;  int SC_INTERNAL_SERVER_ERROR = 500;  int SC_NOT_IMPLEMENTED = 501;  int SC_BAD_GATEWAY = 502;  int SC_SERVICE_UNAVAILABLE = 503;  int SC_GATEWAY_TIMEOUT = 504;  int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2、常见应用

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

3、实现重定向

void sendRedirect(String var1) throws IOException;

重定向:response.sendRedirect() 可以使用相对路径和绝对路径

当浏览器想服务器发起了一个http请求时,如:http:localhost:8080/myapp/user/Test1

相对路径:response.sendRedirect("Login") 容器相对于原来请求URL的目录加参数来生成完整的URL—http:localhost:8080/myapp/user/Login

绝对路径 :response.sendRedirect("/Login") 容器相对于Web应用本身加参数建立完整的URL—http:localhost:8080/Login

转发:request.getRequestDispatcher()也可以使用相对路径和绝对路径

相对路径:request.getRequestDispatcher("Login") 容器相对于原来请求URL的目录加参数来生成完整的URL—http:localhost:8080/myapp/user/Login

绝对路径 :request.getRequestDispatcher("/Login") 容器相对于当前的Web应用本身加参数建立完整的URL—http:localhost:8080/myapp/Login

6.7、HttpServletRequest

1、请求数据

请求行:GET/request-demo/req1?username=zhangsan&password=123 HTTP/1.1

String getMethod()获取请求方式:GETString getContextPath()获取虚拟目录(项目访问路径):/request-demoStringBuffer getRequestURL()获取URL(统一资源定位符):http://localhost:8080/request-demo/req1String getRequestURI()获取URI(统一资源标识符):/request-demo/req1String getQueryString()获取请求参数(GET方式):username=zhangsan&password=123

请求头:User-Agent:Mozilla/5.0 Chrome/91.0.4472.106String getHeader(String name)根据请求头名称,获取值

请求体:username=superbaby&password=123ServletputStream getInputStream()获取字节输入流BufferedReader getReader()获取字符输入流Request-通用方式获取请求参数(对get和post方式都一样)Map getParameterMap()获取所有参数Map集合String[] getParameterValues(String name)根据名称获取参数值(数组)String getParameter(String name)根据名称获取参数值(单个值)

解决中文乱码问题POSTrequest.setCharacterEncoding("UTF-8")GET(下面的方法也可以用于POST)乱码原因:tomcat解码的默认字符集是ISO-8859-1

解决方法先对乱码数据进行编码:转为字节数组byte[] bytes = username.getBytes(StandardCharsets.IOS_8859_1);字节数组解码username = new String(bytes, StandardCharsets.UTF_8);username即还原为中文字符串

请求转发:一种在服务器内部的资源跳转方式实现方式:req.getRequestDispatcher("转发资源路径").forward(req.resp);请求转发资源间共享数据:使用Request对象void setAttribute(String name, Object o)存储数据到request域中Object getAttribute(String name)根据key,获取值void removeAttribute(String name)根据key,删除该键值对

请求转发特点浏览器地址栏路径不发生变化只能转发到当前服务器的内部资源一次请求,可以在转发的资源间使用request共享数据

7、Cookie、Session

7.1、会话

会话:用户打开了浏览器,打开了很多个连接,访问了多个超链接,关闭浏览器这个过程可以称之为会话有状态会话:用户来过网站,下次再来这个网站的时候,网站可以知道这个用户

7.2、保存会话的两种技术

1、cookie:客户端技术

  • 客户端会话技术,将数据保存在客户端,以后每次请求都携带Cookie数据进行访问

应用:记录客户端上一次登陆的时间

PrintWriter out = resp.getWriter();  Cookie[] cookies = req.getCookies();  if(cookies.length != 0){      for (int i = 0; i < cookies.length; i++) {          Cookie cookie = cookies[i];          if(cookie.getName().equals("lastLoginTime")){              out.print("你上一次登陆的时间是"+new Date(Long.parseLong(cookie.getValue())).toString());          }      }  }  resp.addCookie(new Cookie("lastLoginTime",System.currentTimeMillis()+""));

Cookie的常用方法

public void setMaxAge(int expiry) {      this.maxAge = expiry;  }    public int getMaxAge() {      return this.maxAge;  }public String getName() {      return this.name;  }    public void setValue(String newValue) {      this.value = newValue;  }    public String getValue() {      return this.value;  }

Cookie使用细节Cookie存活时间默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁setMaxAge(int seconds):设置Cookie存活时间正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁零:删除对应Cookie

Cookie存储中文Cookie不能直接存储中文如需要存储,则需要进行转码:URL编码URLEncoder.eccode("需要编码的内容", "UTF-8");

2、session:服务端技术

session是由服务器创建的服务器第一次接收到请求时,开辟了一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应;客户端收到响应后,在本机客户端设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束接下来客户端每次向同一个网站发送请求时,请求头都会带上该 Cookie信息(包含 sessionId ), 然后,服务器通过读取请求头中的 Cookie 信息,获取名称为 JSESSIONID 的值,得到此次请求的 sessionId。

session生成大概是,首先你发个请求去服务端,如果你的cookie里面有他之前写的session(叫什么都ok,jsessionid或者其他都行,取决于容器的实现),那么直接读取容器内存该sessionid对应的信息

如果是第一次请求,分2种情况:

1,如果服务端调用获取或设置session的方法,但是传过来的cookie里面没有(根本没cookie可传过去),那么自动生成一个session,并在响应头里面加上Set-Cookie,向浏览器申请写入cookie

2,如果服务端没有调用获取或设置session的方法,那么就不会生成并下发session,应该是为了节省网络以及服务器资源。

什么是session?

  • 服务端会话跟踪技术:将数据保存到服务端
  • 服务器会给每一个用户创建一个session对象
  • 一个session独占一个浏览器,只要浏览器没有关,这个session就存在
  • 用户登陆之后,整个网站都可以共用信息
  • 一些常用方法

session和cookie的区别

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

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据,我们将它保存在Session中;
在一个servlet中存储数据protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {      HttpSession session = req.getSession();      session.setAttribute("p1",new Person("张三",22));  }在一个servlet中读取数据protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {      req.setCharacterEncoding("utf-8");      resp.setCharacterEncoding("utf-8");      resp.setContentType("text/html");          HttpSession session = req.getSession();      Person p1 = (Person)session.getAttribute("p1");      PrintWriter out = resp.getWriter();      out.write(p1.getName()+p1.getAge());  }

JavaEE提供HttpSession接口,来实现一次会话的多次请求间数据共享功能

Session基本使用获取Session对象HttpSession session = request.getSession();

Session对象功能void setAttribute(String name, Object o)存储数据到session域中Object getAttribute(String name)根据key,获取值void removeAttribute(String name)根据key,删除该键值对

Session原理Session是基于Cookie实现的

Session使用细节Session钝化、活化服务器重启后,Session中的数据是否还在?钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中活化:再次启动服务器后,从文件中加载数据到Session中

Session销毁默认情况下,无操作,30分钟自动销毁(在web.xml中配置)

30

Cookie和Session总结Cookie和Session都是来完成一次会话内多次请求间数据共享的

区别

  • 存储位置:Cookie实践爱那个数据存储在客户端,Session将数据存储在服务端
  • 安全性:Cookie不安全,Session安全
  • 数据大小:Cookie最大3KB,Session无大小限制
  • 存储时间:Cookie可以长期存储,Session默认30分钟
  • 服务器性能:Cookie不占服务器资源,Session占用服务器资源

8、JSP

8.1、什么是jsp?

java server pages :java 服务器端页面,也和servlet一样,用于动态web技术

最大的特点:

  • 写jsp就像是在写html
  • 区别
    • HTML只给用户提供静态数据
    • jsp中可以嵌入java代码,为用户提供动态数据

8.2、jsp原理

思路:jsp是怎么执行的jsp本质就是servlet最后还是httpservlet的子类

在类里面内置一些对象向客户端输出的是字符串:输出页面前增加的代码:以上对象我们的都可以直接使用

8.3、jsp的基础语法

1、jsp表达式

<%= %><%= new java.util.Date()%>

2、脚本片段

<%%><%      for (int i = 0; i < 100; i++) {          out.println("

"+i+"


"); } %>

3、jsp声明

<%!%>

4、jsp注释

<%--  注释   --%>

8.4、jsp指令

<%@ page ......   %>.......

8.5、九大内置对象

JSP 中定义了 9 个内置对象,它们分别是:request、response、session、application、out、pagecontext、config、page 和 exception,这些对象在客户端和服务器端交互的过程中分别完成不同的功能。

JSP 的内置对象主要有以下特点:

  • 由 JSP 规范提供,不用编写者实例化;
  • 通过 Web 容器实现和管理;
  • 所有 JSP 页面均可使用;
  • 只有在脚本元素的表达式或代码段中才能使用。

8.6、四大域对象

在 JSP 九大内置对象中,包含四个域对象,它们分别是:pageContext(page 域对象)、request(request 域对象)、session(session 域对象)、以及 application(application 域对象)。

JSP 中的 4 个域对象都能通过以下 3 个方法,对属性进行保存、获取和移除操作。

JSP 中的 4 个域对象的作用域各不相同,如下表。

存储数据:pageContext. setAttribute("name1", "1号"); //保存的数据只在-一个页面中有效request. setAttribute("name2","2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据session. setAttribute("name3", "3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器applicati on. setAttribute ("name4","4号"); //保存的数据只在服务 器中有效,从打开服务器到关闭服务器取出数据://从pageContext取出,我们通过寻找的方式来String name1 = (String) pageContext. findAttribute("name1");String name2 = (String) pageContext. findAttribute("name2");String name3 = (String) pageContext. findAttribute("name3");String name4 = (String) pageContext. findAttribute("name4");String name5 = (String) pageContext. findAttribute("name5");request: 客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!session: 客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;application:客户端向服务器发送请求,产生的数据,-个用户用完了,其他用户还可能使用,比如:聊天数据;

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

1、JSP标签

  • < jsp:forward>该标签的作用是把请求转发给另外一个资源,页面中使用该指令之后,当前页面中的所有要显示的内容都将无法显示,因为会直接转发到了另一个页面。

  • < jsp:include>该标签用于把另外一个文件引入到当前JSP里面,这种引入方式叫做动态引入。

动态引入和静态引入的区别

静态引入:

<%@ include file="/xxx.jsp" %>

静态引入会生成一个java文件,两个jsp文件中可以共享同一个变量,但不能定义重名的变量。

动态引入:

动态引入会生成两个java文件,两个jsp文件中不可以共享同一个变量,可以定义重名的变量。

在静态引入与动态引入均可使用时,一般使用静态引入。因为在程序运行时只存在一个Servlet,对资源的消耗较少,且不存在调用问题,执行效率较高。

2、EL表达式

EL 全名为Expression Language。EL主要作用:

  • 获取数据EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)

  • 执行运算利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${ }

  • 获取web开发常用对象EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。

  • 调用Java方法EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。

使用EL表达式获取数据语法:"${标识符}"  EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。  EL表达式可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据

实例:

<%     request.setAttribute("name","孤傲苍狼"); %>     <%--${name}等同于pageContext.findAttribute("name") --%>     使用EL表达式获取数据:${name}       <%     Person p = new Person();     p.setAge(12);     request.setAttribute("person",p); %>     使用el表达式可以获取bean的属性:${person.age}       <%     Person person = new Person();     Address address = new Address();     person.setAddress(address);     request.setAttribute("person",person); %>    ${person.address.name}      <%     Person p1 = new Person();     p1.setName("孤傲苍狼");     Person p2 = new Person();     p2.setName("白虎神皇");     List list = new ArrayList();     list.add(p1);     list.add(p2);     request.setAttribute("list",list); %>  ${list[1].name}       ${person.name}   <%     Map map = new LinkedHashMap();     map.put("a","aaaaxxx");     map.put("b","bbbb");     map.put("c","cccc");     map.put("1","aaaa1111");     request.setAttribute("map",map); %>    ${map.c}   ${map["1"]}      ...                 

我的工资为:

本身只当做的父标签(感觉和 while 一样用)

的子标签,用来判断条件是否成立

的子标签,接在标签后,当标签判断为false时被执行

            ...                ...        ...    ...            ...    

你的工资为 :

太惨了 不错的薪水,还能生活。 什么都没有。

其他: 用于保存数据(作用和out差不多)

用于删除数据

用来处理产生错误的异常状况,并且将错误信息储存起来

检索一个绝对或相对 URL,然后将其内容暴露给页面

根据指定的分隔符来分隔内容并迭代输出(相比而言,标签是更加通用的标签)

用来给包含或重定向的页面传递参数

重定向至一个新的URL.

使用可选的查询参数来创造一个URL

9、JavaBean

JavaBen:实体类

JavaBean有特定的写法:

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

一般用来和数据库的字段做映射ORM :对象关系映射

  • 表-->类
  • 字段-->属性
  • 行记录--->对象
<%//People people = new People();//people. setAddress();//people. setId();//people. setAge();//people. setName();%>姓名: id: 年龄: 地址: 

10、MVC三层架构

10.1、介绍

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

在以前,项目是这样分成的:

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

servlet--CRUD-->数据库

弊端:

  • 程序十分臃肿,不利于维护
  • serv1et的代码中: 处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

MVC三层架构:

Model

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

View .

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

Controller (Servlet)

  • 接收用户的请求: (req: 请求参数、Session信....
  • 交给业务层处理对应的代码
  • 控制视图的跳转

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

11、Filter

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

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

编写Filter步骤:

  1. 导包
  2. 实现Filter接口
  3. 重写doFilter方法
  4. 配置web.xml文件
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("执行前");      chain.doFilter(request,response);      System.out.println("执行后");  }

11.1、登陆小demo

1、登陆servlet

public class LoginServlet extends HttpServlet {      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          String name = req.getParameter("name");          if(name.equals("admin")){              req.getSession().setAttribute("USER_SESSION",req.getSession().getId());              resp.sendRedirect("/Filter/sys/Home.html");          }else {              resp.sendRedirect("/Filter/sys/error.html");          }      }        @Override      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          doGet(req, resp);      }  }

2、注销

public class LoginOut extends HttpServlet {      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          req.getSession().removeAttribute("USER_SESSION");          resp.sendRedirect("/Filter/Login.html");      }        @Override      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          doGet(req, resp);      }  }

3、过滤器

public class LoginFilter implements Filter {      @Override      public void init(FilterConfig filterConfig) throws ServletException {          Filter.super.init(filterConfig);      }        @Override      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {          HttpServletRequest req = (HttpServletRequest) request;          HttpServletResponse resp = (HttpServletResponse) response;            resp.setDateHeader("Expires",-1);          resp.setHeader("Cache-Control","no-cache");          resp.setHeader("Pragma","no-cache");            if(req.getSession().getAttribute("USER_SESSION") != null){              chain.doFilter(req,resp);          }else {              resp.sendRedirect("/Filter/Login.html");          }        }        @Override      public void destroy() {          Filter.super.destroy();      }  }

注意浏览器缓存机制因为浏览器缓存,会导致注销登陆之后回退或者不刷新会回到登陆的状态,但是此时我们已经注销账户了

解决:设置响应头,让浏览器不缓存

response.setDateHeader("Expries", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache");

12、监听器

public class Listener01 implements HttpSessionListener {      @Override      public void sessionCreated(HttpSessionEvent se) {          System.out.println("创建了一个session");          System.out.println(se.getSession().getId());          ServletContext servletContext = se.getSession().getServletContext();          if(servletContext.getAttribute("userNum") != null){              int newNum = ((int) servletContext.getAttribute("userNum")) +1;              servletContext.setAttribute("userNum",newNum);          }else {              servletContext.setAttribute("userNum",1);          }      }        @Override      public void sessionDestroyed(HttpSessionEvent se) {          System.out.println(se.getSession().getId());          ServletContext servletContext = se.getSession().getServletContext();          int newNum = ((int) servletContext.getAttribute("userNum")) - 1;          servletContext.setAttribute("userNum",newNum);      }  }

13、SMBMS项目

13.1、搭建项目

  1. 搭建一个maven项目
  2. 配置tomcat
  3. 导入依赖
  4. 创建项目包结构
  5. 建实体类:ORM映射 表---->类
  6. 编写基础公共类
    1. 数据库配置文件
    2. 编写基础DAO类的crud
    3. 编写字符编码过滤器
  7. 导入静态资源

13.2、登陆注销实现

1、登陆servlet

public class LoginServlet extends HttpServlet {        private LoginService loginService = new LoginService();      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          String userCode = req.getParameter("userCode");          String userPassword = req.getParameter("userPassword");          User user = loginService.LoginUser(userCode, userPassword);          if(user != null){              //Constant.USER_SESSION = userSession              //userSession为前端获取Javabean对象的属性              //${userSession.userName }会调用user类的get方法,所以必须拥有get方法才可以获取              req.getSession().setAttribute(Constant.USER_SESSION,user);              resp.sendRedirect(req.getContextPath()+"/jsp/frame.jsp");          }else{              //登陆错误前端需要获取error信息,这里把错误信息的kv放在req里面转发给前端              //
${error}
req.setAttribute("error","登陆错误,请检查账号密码是否正确"); req.getRequestDispatcher("/login.jsp").forward(req,resp); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }

2、注销servlet

public class LoginOut extends HttpServlet {      @Override      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          //将对应session的kv移除,属性为空则表示非登陆状态          req.getSession().removeAttribute(Constant.USER_SESSION);          resp.sendRedirect(req.getContextPath()+"/login.jsp");      }        @Override      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {          doGet(req, resp);      }  }

3、拦截器:用户注销之后还可以直接进入主页,需要根据session的userSession值是否存在,来拦截对应请求

public class LoginFilter implements Filter {      @Override      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {          HttpServletRequest req = (HttpServletRequest) request;          HttpServletResponse resp = (HttpServletResponse)response;            if(req.getSession().getAttribute(Constant.USER_SESSION) == null){//未登陆              resp.sendRedirect(req.getContextPath()+"/error.jsp");          }else {          //注意这里是原来的request,response            chain.doFilter(request,response);          }      }  }

13.2、密码修改

关键词: 发送请求 存储数据 绝对路径