狂神javaweb教学视频全套学习笔记,详细的介绍了一下知识点: Tomcat、Http、Maven、Servlet、Cookie 和 Session、JSP、JAVABEEN、MVC三层框架、过滤器、监听器、JDBC
JavaWeb
1、整体框架来源于狂神的视频笔记,此处贴一个狂神自制的网站https://www.kuangstudy.com/ 2、我参考了语雀“青梅换了酒”的笔记,本文大多数流程图也来源于此佬,此处贴来源链接https://www.yuque.com/lajinsinlearn/lpn02c 3、本文的整理工作以及大部分运行结果截图为本人所做,保留权利
1、基本概念 1.1、前言 web开发:
静态web
html,css
提供给所有人看的数据始终不会发生变化!
动态web
淘宝,甚至几乎是所有的网站;每个人看到的东西都不一样
技术栈:Servlet/JSP,ASP,PHP
在Java中,动态web资源开发的技术统称为JavaWeb;
1.2、web应用程序 web应用程序:可以提供浏览器访问的程序;web应用程序–>Tomcat:服务器
a.html、b.html……多个web资源,这些web资源可以被外界访问,对外界提供服务;
一个web应用由多部分组成 (静态web,动态web)
html,css,js
jsp,servlet
Java程序
jar包
配置文件 (Properties)
1.3、静态web
*.htm, *.html,这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。
静态web存在的缺点
Web页面无法动态更新,所有用户看到都是同一个页面
轮播图,点击特效:伪动态
JavaScript [实际开发中,它用的最多]
它无法和数据库交互(数据无法持久化,用户无法交互)
1.4、动态web 页面会动态展示: “Web的页面展示的效果因人而异”;
缺点:
加入服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序 ,重新发布;也就是需要停机维护
优点:
Web页面可以动态更新,所有用户看到都不是同一个页面
它可以与数据库交互 (数据持久化:注册,商品信息,用户信息……..)
2、web服务器 2.1、技术讲解 ASP:
在ASP开发中,基本一个页面都有几千行的业务代码,页面极其换乱,维护成本高!
php:
PHP开发速度很快,功能很强大,跨平台,代码很简单 (70% , WP)
无法承载大访问量的情况(局限性)
**JSP/Servlet : **
B/S:浏览和服务器
C/S: 客户端和服务器
sun公司主推的B/S架构
基于Java语言的 (所有的大公司,或者一些开源的组件,都是用Java写的)
可以承载三高问题带来的影响;
2.2、web服务器 服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息;
Tomcat
最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,因为Tomcat 技术先进、性能稳定,而且免费 ,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器 ,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。 对于一个Java初学web的人来说,它是最佳的选择
Tomcat 实际上运行JSP 页面和Servlet。Tomcat最新版本为9.0。
3、Tomcat 安装和配置不再叙述、可看狂神笔记。
3.1、发布一个web网站 不会就先模仿
将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了
网站应该有的结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 --webapps :Tomcat服务器的web目录 -ROOT -kuangstudy :网站的目录名 - WEB-INF -classes : java程序 -lib:web应用所依赖的jar包 -web.xml :网站配置文件 - index.html 默认的首页 - static -css -style.css -js -img -.....
4、Http 4.1、什么是HTTP HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。
http1.0
HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
http2.0
HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。‘
4.2、Http请求
1 2 3 4 5 Request URL:https: Request Method:GET get方法/post方法 Status Code:200 OK 状态码:200 Remote(远程) Address:14.215 .177.39 :443
1、请求行
请求行中的请求方式:GET
请求方式:Get,Post ,HEAD,DELETE,PUT,TRACT…(面试题)
get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。
2、消息头
Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding: 支持的编码格式 UTF-8 GBK GB2312
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 请求完成是断开还是保持连接
1 2 3 4 5 Accept:text/html Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.9 语言 Cache-Control:max-age=0 Connection:keep-alive
4.3、Http响应
1 2 3 4 5 Cache-Control:private 缓存控制 Connection:Keep-Alive 连接 Content-Encoding:gzip 编码 Content-Type:text/html 类型
1.响应体 1 2 3 4 5 6 7 8 Accept:告诉浏览器,它所支持的数据类型 Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1 Accept-Language:告诉浏览器,它的语言环境 Cache-Control:缓存控制 Connection:告诉浏览器,请求完成是断开还是保持连接 HOST:主机..../. Refresh:告诉客户端,多久刷新一次; Location:让网页重新定位;
2、响应状态码 200:请求响应成功 200
3xx:请求重定向 ,重定向:你重新到我给你新位置去;
4xx:找不到资源 404,资源不存在;
5xx:服务器代码错误 500 502:网关错误
5、Maven 我为什么要学习这个技术?
在Javaweb开发中,需要使用大量的jar包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。
由此,Maven诞生了!
5.1 Maven项目架构管理工具 我们目前用来就是方便导入jar包的!
Maven的核心思想:约定大于配置 :有约束,就不要去违反。
Maven会规定好你该如何去编写我们的Java代码,必须要按照这个规范来;
5.2 下载安装Maven 官网;https://maven.apache.org/
下载完成后,解压即可;
小狂神友情建议:电脑上的所有环境都放在一个文件夹下,方便管理;
5.3 配置环境变量 在我们的系统环境变量中
配置如下配置:
M2_HOME maven目录下的bin目录 ??这个我没配
MAVEN_HOME maven的目录
在系统的path中配置 %MAVEN_HOME%\bin
测试Maven是否安装成功,保证必须配置完毕!
5.4 阿里云镜像
1 2 3 4 5 6 <mirror > <id > nexus-aliyun</id > <mirrorOf > *,!jeecg,!jeecg-snapshots</mirrorOf > <name > Nexus aliyun</name > <url > http://maven.aliyun.com/nexus/content/groups/public</url > </mirror >
5.5 本地仓库 在本地的仓库,远程仓库;
建立一个本地仓库: localRepository
1 <localRepository > D:\Environment\apache-maven-3.6.2\maven-repo</localRepository >
5.6、在IDEA中使用Maven
启动IDEA
创建一个MavenWeb项目
等待项目初始化完毕
观察maven仓库中多了什么东西?
IDEA中的Maven设置
注意:IDEA项目创建成功后,看一眼Maven的配置
到这里,Maven在IDEA中的配置和使用就OK了!
5.9 在 IDEA中配置Tomcat
解决警告问题
必须要的配置:为什么会有这个问题:我们访问一个网站,需要指定一个文件夹名字;
5.10 pom文件 pom.xml 是Maven的核心配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 <?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.kuang</groupId > <artifactId > javaweb-01-maven</artifactId > <version > 1.0-SNAPSHOT</version > <packaging > war</packaging > <properties > <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding > <maven.compiler.source > 1.8</maven.compiler.source > <maven.compiler.target > 1.8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.11</version > </dependency > </dependencies > <build > <finalName > javaweb-01-maven</finalName > <pluginManagement > <plugins > <plugin > <artifactId > maven-clean-plugin</artifactId > <version > 3.1.0</version > </plugin > <plugin > <artifactId > maven-resources-plugin</artifactId > <version > 3.0.2</version > </plugin > <plugin > <artifactId > maven-compiler-plugin</artifactId > <version > 3.8.0</version > </plugin > <plugin > <artifactId > maven-surefire-plugin</artifactId > <version > 2.22.1</version > </plugin > <plugin > <artifactId > maven-war-plugin</artifactId > <version > 3.2.2</version > </plugin > <plugin > <artifactId > maven-install-plugin</artifactId > <version > 2.5.2</version > </plugin > <plugin > <artifactId > maven-deploy-plugin</artifactId > <version > 2.8.2</version > </plugin > </plugins > </pluginManagement > </build > </project >
maven由于他的约定大于配置,我们之后可以能遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <build > <resources > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > true</filtering > </resource > <resource > <directory > src/main/java</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > true</filtering > </resource > </resources > </build >
Maven仓库的使用
地址:https://mvnrepository.com/
6、Servlet 6.1、Servlet简介
Servlet就是sun公司开发动态web的一门技术
Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
编写一个类,实现Servlet接口
把开发好的Java类部署到web服务器中。
6.2、HelloServlet Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
编写一个Servlet程序
1、在com.kuang.servlet包下写一个某某servlet类 比如HelloServlet 继承HttpServlet类、并重写doGet()、doPost()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class HelloServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.print("Hello,Serlvet" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
2、在web.xml里面编写Servlet的映射
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;
1 2 3 4 5 6 7 8 9 10 11 12 <servlet > <servlet-name > hello</servlet-name > <servlet-class > com.kuang.servlet.HelloServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping >
3、配置Tomcat注意:配置项目发布的路径就可以了。注意tomcat里面也有个路径、访问时要带上。
4、启动测试,OK!
6.3、Servlet原理 Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:
6.4、Mapping问题
一个Servlet可以指定一个映射路径
1 2 3 4 <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping >
一个Servlet可以指定多个映射路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello2</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello3</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello4</url-pattern > </servlet-mapping > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello5</url-pattern > </servlet-mapping >
一个Servlet可以指定通用映射路径
1 2 3 4 <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello/*</url-pattern > </servlet-mapping >
默认请求路径
1 2 3 4 5 <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /*</url-pattern > </servlet-mapping >
指定一些后缀或者前缀等等….
1 2 3 4 5 6 7 8 <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > *.qinjiang</url-pattern > </servlet-mapping >
优先级问题 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
1 2 3 4 5 6 7 8 9 10 <servlet > <servlet-name > error</servlet-name > <servlet-class > com.kuang.servlet.ErrorServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > error</servlet-name > <url-pattern > /*</url-pattern > </servlet-mapping >
6.5、ServletContext web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
1、共享数据 我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class HelloServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String username = "秦疆" ; context.setAttribute("username" ,username); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class GetServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String username = (String) context.getAttribute("username" ); resp.setContentType("text/html" ); resp.setCharacterEncoding("utf-8" ); resp.getWriter().print("名字" +username); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <servlet > <servlet-name > hello</servlet-name > <servlet-class > com.kuang.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.kuang.servlet.GetServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > getc</servlet-name > <url-pattern > /getc</url-pattern > </servlet-mapping >
测试访问结果:(这里s2是tomcat中设置的路径)
2、获取初始化参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <context-param > <param-name > url</param-name > <param-value > jdbc:mysql://localhost:3306/mybatis</param-value > </context-param > <servlet > <servlet-name > getp</servlet-name > <servlet-class > edu.cqupt.servlet.Servlet03</servlet-class > </servlet > <servlet-mapping > <servlet-name > getp</servlet-name > <url-pattern > /getp</url-pattern > </servlet-mapping >
1 2 3 4 5 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String url = context.getInitParameter("url" ); resp.getWriter().print(url); }
测试结果: (这里s2是tomcat中设置的路径)
3、请求转发
1 2 3 4 5 6 7 8 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); System.out.println("进入了ServletDemo04" ); context.getRequestDispatcher("/gp" ).forward(req,resp); }
测试结果:请求由ServletDemo04的路径/getp转发到/gp的Servlet
4、读取资源文件Properties (以后一般不用这样麻烦的读取了)
1 需要在本项目的pom.xml中配置resources:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <build > <resources > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > true</filtering > </resource > <resource > <directory > src/main/java</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > true</filtering > </resource > </resources > </build >
2 写db.properties :
1 2 username =root password =123456
3 需要一个文件流:Servlet05.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Servlet05 extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this .getServletContext().getResourceAsStream("/WEB-INF/classes/db.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); } }
4 配置web.xml
1 2 3 4 5 6 7 8 <servlet > <servlet-name > sd5</servlet-name > <servlet-class > edu.cqupt.servlet.Servlet05</servlet-class > </servlet > <servlet-mapping > <servlet-name > sd5</servlet-name > <url-pattern > /sd5</url-pattern > </servlet-mapping >
测试结果:
6.6、HttpServletResponse(响应) 请求和响应:
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
1、响应的简单分类
1 2 ServletOutputStream getOutputStream () throws IOException ;PrintWriter getWriter () throws IOException ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void setCharacterEncoding (String var1) ;void setContentLength (int var1) ;void setContentLengthLong (long var1) ;void setContentType (String var1) ;void setDateHeader (String var1, long var2) ;void addDateHeader (String var1, long var2) ;void setHeader (String var1, String var2) ;void addHeader (String var1, String var2) ;void setIntHeader (String var1, int var2) ;void addIntHeader (String var1, int var2) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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、响应常见应用 a.向浏览器输出消息 (resp.getwriter().print())
b.下载文件 1 2 3 4 5 6 7 8 获取下载文件的路径 下载的文件名 设置想办法让浏览器能够支持下载我们需要的东西 获取下载文件的输入流 创建缓冲区 获取OutputStream对象 将FileOutputStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
c.验证码功能 1 2 前端实现 后端实现,需要用到 java 的图片类,生成一个图片
d.实现重定向(就是常用的页面跳转功能)
解释:B一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向。常见场景: 用户登录:登录成功,跳转到另外的页面。
实现步骤如下:
1 在index.jsp文件中写一个表单和提交按钮
1 2 3 4 5 6 7 8 <%--这里提交的路径,需要寻找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前的项目--%> <%-- /login表示输入路径是这个时 就跳到这个index.jsp文件中来了 --%> <form action="${pageContext.request.contextPath}/login" method="get" > 用户名:<input type="text" name="username" > <br> 密码:<input type="password" name="password" > <br> <input type="submit" > </form>
2 在com.kuang.servlet包下写一个某某servlet类 比如RequestTestServlet 继承HttpServlet类
类里面重写doGet() 和doPost()方法
方法里面写重定向的方法,重定向到某个jsp文件(含表单和提交按钮)
resp.sendRedirect(“/S2/index.jsp”);
其中s2表示tomcatl里面设置的路径
或者自己想实现的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class RequestTestServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入这个请求了----" ); String username = req.getParameter("username" ); String pwd = req.getParameter("password" ); System.out.println(username + ":" + pwd); resp.sendRedirect("/s2/home.jsp" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
3 写配置,在web.xml里面写servlet定位文件和url的配置
1 2 3 4 5 6 7 8 9 10 <servlet > <servlet-name > request</servlet-name > <servlet-class > com.kuang.servlet.RequestTestServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > request</servlet-name > <url-pattern > /login</url-pattern > </servlet-mapping >
4 写重定向要访问的jsp页面
1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1> Success_wk</h1> </body> </html>
5 配置tomcat,注意要选择当前项目的servlet-03.war包,并修改里面的路径
6.7、HttpServletRequest(请求) HttpServletRequest代表客户端的请求,HTTP请求中的所有信息会被封装到HttpServletRequest,我们也正是通过这个HttpServletRequest的方法,来获得客户端的所有信息;
1、HttpServletRequest请求的一些get方法:
2、获取前端传递的参数和请求转发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class LoginServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("utf-8" ); req.setCharacterEncoding("utf-8" ); String username = req.getParameter("username" ); String password = req.getParameter("password" ); String[] hobbies = req.getParameterValues("hobbies" ); System.out.println("---------------" ); System.out.println(username); System.out.println(password); System.out.println(Arrays.toString(hobbies)); System.out.println("---------------" ); System.out.println(req.getContextPath()); req.getRequestDispatcher("/success.jsp" ).forward(req,resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
面试题:请你聊聊重定向和转发的区别?
相同点
不同点
请求转发的时候,url不会产生变化 307
重定向时候,url地址栏会发生变化; 302
7、Cookie 和 Session 7.1、会话 会话 :用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;
有状态会话 :一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;
一个网站,怎么证明你来过?
保存会话的两种技术
常见常见:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!
7.2、Cookie实现
从请求中拿到cookie信息
服务器响应给客户端cookie
1 2 3 4 5 6 Cookie[] cookies = req.getCookies(); cookie.getName(); cookie.getValue(); new Cookie("lastLoginTime" , System.currentTimeMillis()+"" ); cookie.setMaxAge(24 *60 *60 ); resp.addCookie(cookie);
删除Cookie;
不设置有效期,关闭浏览器,自动失效;
设置有效期时间为 0 ;
Cookie实现步骤:
1、建一个webpage的maven项目名为javewen-session-cookie。
新建java和resources包,,
更新web.xml到最新,,
删除多的pom.xml,只加入几个重要依赖
1 2 3 4 5 6 7 8 <?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" metadata-complete ="true" > </web-app >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <dependencies > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 4.0.1</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > javax.servlet.jsp-api</artifactId > <version > 2.3.3</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</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 > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency > </dependencies >
2、写servlet
java下写一个com.kuang.servlet包 ,包里面写CookieDemo01类继承httpServlet;
重写doGet() doPost()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package com.kuag.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 { resp.setCharacterEncoding("utf-8" ); req.setCharacterEncoding("utf-8" ); resp.setContentType("text/html" ); PrintWriter out = resp.getWriter(); Cookie[] cookies = req.getCookies(); if (cookies!=null ){ out.write("你上次访问的时间是:" ); for (int i = 0 ; i <cookies.length ; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals("lastLoginTime" )){ long lastLoginTime = Long.parseLong(cookie.getValue()); Date date = new Date(lastLoginTime); out.write(date.toLocaleString()); } System.out.println(cookie.getName()); } }else { out.write("这是您第一次访问本网站。" ); } Cookie cookie = new Cookie("lastLoginTime" , System.currentTimeMillis() + "" ); cookie.setMaxAge(24 *60 *60 ); resp.addCookie(cookie); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
3、web.xml中配置路径和访问url
1 2 3 4 5 6 7 8 9 <servlet > <servlet-name > CookieDemo01</servlet-name > <servlet-class > com.kuag.servlet.CookieDemo01</servlet-class > </servlet > <servlet-mapping > <servlet-name > CookieDemo01</servlet-name > <url-pattern > /c1</url-pattern > </servlet-mapping >
4、配置Tomcat、跑起来,就ok了。
7.3、Session(重点)
什么是Session:
服务器会给每一个用户(浏览器)创建一个Seesion对象;
一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
用户登录之后,整个网站它都可以访问!–> 保存用户的信息;保存购物车的信息…..
使用场景:
保存一个登录用户的信息;
购物车信息;
在整个网站中经常会使用的数据,我们将它保存在Session中;
Session和Cookie的区别:
Cookie是把用户的数据写给用户得浏览器,浏览器保存(可以保存多个)
Session把用户的数据写到用户独占的Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
Session对象由服务器创建
Session的实步骤:
1、写一个Person实体类,成员变量为name age(只是为了测试、非必要)
2、写servlet包里面写SessionDemo01类继承httpServlet,并重写doGet() doPost()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package com.kuag.servlet;import com.kuag.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 SessionDemo01 extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8" ); resp.setCharacterEncoding("UTF-8" ); resp.setContentType("text/html;charset=utf-8" ); HttpSession session = req.getSession(); String sessionId = session.getId(); if (session.isNew()){ resp.getWriter().write("session创建成功,ID:" +sessionId); }else { resp.getWriter().write("session以及在服务器中存在了,ID:" +sessionId); } session.setAttribute("name" ,"wukang" ); String name = (String) session.getAttribute("name" ); System.out.println(name); session.setAttribute("name" ,new Person("wukang" ,20 )); 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); } }
3、配置web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <servlet > <servlet-name > SessionDemo01</servlet-name > <servlet-class > com.kuag.servlet.SessionDemo01</servlet-class > </servlet > <servlet-mapping > <servlet-name > SessionDemo01</servlet-name > <url-pattern > /s1</url-pattern > </servlet-mapping > <session-config > <session-timeout > 15</session-timeout > </session-config >
8、JSP 8.1、什么是JSP Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术!
JSP最大的特点:
写JSP就像在写HTML
区别:
HTML只给用户提供静态的数据
JSP页面中可以嵌入JAVA代码,为用户提供动态数据;
8.2、JSP原理 思路:JSP到底怎么执行的!
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终也会被转换成为一个Java类!
JSP 本质上就是一个Servlet
1 2 3 4 5 6 7 8 public void _jspInit () { } public void _jspDestroy () { } public void _jspService (.HttpServletRequest request,HttpServletResponse response)
判断请求
内置一些对象
1 2 3 4 5 6 7 8 final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null ; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null ; final java.lang.Object page = this ; HttpServletRequest request HttpServletResponse response
输出页面前增加的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 response.setContentType("text/html" ); 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; out.write("\r\n" ); out.write("\r\n" ); out.write("<html>\r\n" ); out.write("<head>\r\n" ); out.write(" <title>Title</title>\r\n" ); out.write("</head>\r\n" ); out.write("<body>\r\n" ); out.write(" jsp_wk\r\n" ); out.write("</body>\r\n" ); out.write("</html>\r\n" );
以上的这些个对象我们可以在JSP页面中直接使用!
最后再过一遍原理:
1、webapp下面写一个hello.jsp文件
1 2 3 4 5 6 7 8 9 10 11 12 13 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% String name = "wukangzuihsuai" ; %> name:<%=name%> </body> </html>
2、运行tomcat,找到C盘“那个路径”,发现里面只有index_jsp.java 和 index_jsp.class,,,然后浏览器访问http://localhost:8080/hello.jsp发现,多出来两个文件hello_jsp.java 和hello_jsp.class..点java文件看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 out.write("\r\n" ); out.write("\r\n" ); out.write("<html>\r\n" ); out.write("<head>\r\n" ); out.write(" <title>Title</title>\r\n" ); out.write("</head>\r\n" ); out.write("<body>\r\n" ); out.write(" " ); String name = "wukangzuihsuai" ; out.write("\r\n" ); out.write("name:" ); out.print(name); out.write("\r\n" ); out.write("\r\n" ); out.write("</body>\r\n" ); out.write("</html>\r\n" );
3、说明在JSP页面中;只要是 JAVA代码就会原封不动的输出;如果是HTML代码,就会被转换为下面这样的格式,输出到前端!
1 out.write("<html>\r\n" );
8.3、JSP基础语法
任何语言都有自己的语法。 JSP 作为java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可!),Java所有语法都支持!
JSP表达式 1 2 3 4 5 <%--JSP表达式 作用:用来将程序的输出,输出到客户端 <%= 变量或者表达式%> --%> <%= new java.util.Date()%>
jsp脚本片段 1 2 3 4 5 6 7 8 <%--jsp脚本片段--%> <% int sum = 0 ; for (int i = 1 ; i <=100 ; i++) { sum+=i; } out.println("<h1>Sum=" +sum+"</h1>" ); %>
脚本片段的再实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <% int x = 10 ; out.println(x); %> <p>这是一个JSP文档</p> <% int y = 2 ; out.println(x); out.println(y); %> <hr> <%--在代码嵌入HTML元素--%> <% for (int i = 0 ; i < 5 ; i++) { %> <h1>Hello,World <%=i%> </h1> <% } %>
JSP声明 <%! %> 作用域更高了 JSP声明:会被编译到JSP生成Java的类中!其他的,就会被生成到_jspService方法中!
1 2 3 4 5 6 7 8 9 10 11 <%! static { System.out.println("Loading Servlet!" ); } private int globalVar = 0 ; public void kuang () { System.out.println("进入了方法Kuang!" ); } %>
EL表达式${}
1 2 3 <%for (int i = 0 ; i < 5 ; i++) {%> <h1>Hello World! ${i} </h1> <%}%>
JSP的注释:
JSP的注释,不会在客户端显示,HTML的注释会显示!
8.4、JSP指令
跳转错误页面(采用JSP指令)
1在web下建img包,放两个图片:404.png 、500.png
1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <img src="../img/404.png" alt="404" > </body> </html>
1 2 3 4 5 6 7 8 9 10 11 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <img src="../img/500.png" alt="500" > </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%-- 定制错误页面 --%> <%@ page errorPage="/error/500.jsp" %> <html> <head> <title>Title</title> </head> <body> <% int x=1 /0 ; %> </body> </html>
效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <%-- page import 可以用于导包,比如--%> <%@ page import = "java.util.Date" %> <%--@include 会将两个页面合二为一--%> <%@include file="common/header.jsp" %> <h1>网页主体</h1> <%@include file="common/footer.jsp" %> <hr> <%--jSP标签 jsp:include:拼接页面,本质还是三个 --%> <hr> <jsp:include page="/common/header.jsp" /> <h1>网页主体</h1> <jsp:include page="/common/footer.jsp" />
8.5、9大内置对象 jsp变成java文件再编译成class,编译成class会在自动生成这9个对象
PageContext 存东西
Request 存东西
Response
Session 存东西
Application 【SerlvetContext 】 存东西
config 【SerlvetConfig】
out
page ,不用了解
exception
使用4个存东西的内置对象,并取出展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%--内置对象--%> <% pageContext.setAttribute("name1" ,"秦疆1号" ); request.setAttribute("name2" ,"秦疆2号" ); session.setAttribute("name3" ,"秦疆3号" ); application.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" ); %> <%--使用EL表达式输出${}--%> <h1>取出的值为:</h1> <h3>${name1}</h3> <h3>${name2}</h3> <h3>${name3}</h3> <h3>${name4}</h3> </body> </html>
结果显示:
作用域的区别:
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;(下图中每个人一个session,就是s1 s2 s3)
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;(下图中的“库中的商品就是这种”)
8.6、JSP标签、JSTL标签、EL表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 <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 >
EL表达式: ${ }(需要导上面两个包)获取数据、执行运算、获取web开发的常用对象
JSP标签
1 2 3 4 5 6 <%-- jsp:include:拼接页面,本质还是三个 --%> <hr> <jsp:include page="/common/header.jsp" /> <h1>网页主体</h1> <jsp:include page="/common/footer.jsp" />
forward 用来跳转页面
param 用来携带参数
1、写一个页面 jsptag.jsp 跳转和给参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%-- http: forward 用来跳转页面 param 用来携带参数 --%> <jsp:forward page="/jsptag2.jsp" > <jsp:param name="name" value="kuangshen"></jsp:param> <jsp:param name="age" value="12"></jsp:param> </jsp:forward> </body> </html>
2、写一个页面 jsptag2.jsp接受参数和输出显示
1 2 3 4 5 6 7 8 9 10 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title2</title> </head> <body> 名字:<%=request.getParameter("name" )%> 年龄:<%=request.getParameter("age" )%> </body> </html>
结果显示:是第一个页面的路径、是第二个页面的结果
JSTL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!https://www.runoob.com/jsp/jsp-jstl.html
核心标签c 核心标签是最常用的 JSTL标签(掌握部分就好)。引用核心标签库的语法如下(放在jsp头部):
1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL标签库使用步骤
1、引入对应的 taglib
2、使用其中的方法
3、在Tomcat 也需要引入 jstl的包,否则会报错:JSTL解析错误(老版本)
c:if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <head> <title>Title</title> </head> <body> <h4>if测试</h4> <hr> <form action="coreif.jsp" method="get" > <%-- EL表达式获取表单中的数据 ${param.参数名} --%> <input type="text" name="username" value="${param.username}" > <input type="submit" value="登录" > </form> <%--判断如果提交的用户名是管理员,则登录成功--%> <c:if test="${param.username=='admin'}" var ="isAdmin" > <c:out value="管理员欢迎您!" /> </c:if> <%--自闭合标签--%> <c:out value="${isAdmin}" /> </body>
c:choose c:when
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <body> <%--定义一个变量score,值为85 --%> <c:set var ="score" value="55" /> <c:choose> <c:when test="${score>=90}" > 你的成绩为优秀 </c:when> <c:when test="${score>=80}" > 你的成绩为一般 </c:when> <c:when test="${score>=70}" > 你的成绩为良好 </c:when> <c:when test="${score<=60}" > 你的成绩为不及格 </c:when> </c:choose> </body>
c:forEach
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <% 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="1" > <c:out value="${people}" /> <br> </c:forEach>
9、JavaBean 实体类
JavaBean有特定的写法:
必须要有一个无参构造
属性必须私有化
必须有对应的get/set方法;
一般用来和数据库的字段做映射 ORM;
people表
id
name
age
address
1
张三
3
北京
2
李四
18
杭州
3
王五
100
长沙
数据库中的一个表对应建立一个实体类:
1 2 3 4 5 6 7 8 9 10 11 12 class People { private int id; private String name; private int age; private String address; } class A { new People(1 ,"张三" ,3 ,"北京" ); new People(2 ,"李四" ,18 ,"杭州" ); new People(3 ,"王五" ,100 ,"长沙" ); }
10、MVC三层架构 什么是MVC: Model view Controller 模型、视图、控制器
10.1、早些年
用户直接访问控制层,控制层就可以直接操作数据库;
1 2 3 4 5 6 7 8 9 10 11 模式:servlet--CRUD-->数据库 弊端:程序十分臃肿,不利于维护 servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码 改进原则使用架构:没有什么是加一层架构解决不了的! 例如JDBC的使用,可以直接处理多种数据库: 程序猿调用 | JDBC | Mysql Oracle SqlServer ....
10.2、MVC三层架构
Model
业务处理 :业务逻辑(Service)
数据持久层:CRUD (Dao)
View
展示数据
提供链接发起Servlet请求 (a,form,img…)
Controller (Servlet)
11、Filter过滤器(重点) Filter:过滤器 ,用来过滤网站的数据;(在服务器和数据库之间的一道过滤网)
Filter开发步骤:
新建一个maven新项目、导入web支持,然后pom.xml里面导入5个依赖:
Servlet依赖、JSP依赖、JSTL表达式依赖、Standard标签库依赖、连接数据库connector依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 4.0.1</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > javax.servlet.jsp-api</artifactId > <version > 2.3.3</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 > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency >
编写过滤器
导包不要错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.kuang.filter;import javax.servlet.*;import java.io.IOException;public class CharacterEncodingFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化" ); } @Override 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执行后...." ); } @Override public void destroy () { System.out.println("CharacterEncodingFilter销毁" ); } }
在web.xml中配置 Filter。这里实现的功能是“只要是 /servlet/…下的任何请求,会经过这个过滤器”
1 2 3 4 5 6 7 8 9 10 <filter > <filter-name > CharacterEncodingFilter</filter-name > <filter-class > com.kuang.filter.CharacterEncodingFilter</filter-class > </filter > <filter-mapping > <filter-name > CharacterEncodingFilter</filter-name > <url-pattern > /servlet/*</url-pattern > </filter-mapping >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.kuang.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 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); } }
配置web.xml,含两个访问路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 <servlet > <servlet-name > ShowServlet</servlet-name > <servlet-class > com.kuang.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 >
配置Tomcat,运行,并访问servlet的路径。结果如下:发现没有使用过滤器的/show路径发生乱码;而使用了过滤器的/servlet/show的路劲正常显示中文:
12、监听器 实现一个监听器的接口;(有N种)
编写一个监听器
实现监听器的接口…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class OnlineCountListener implements HttpSessionListener { 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); } 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); } }
web.xml中注册监听器
1 2 3 4 <listener > <listener-class > com.kuang.listener.OnlineCountListener</listener-class > </listener >
看情况是否使用!
13、JDBC 什么是JDBC : Java连接数据库!
需要jar包的支持:
java.sql
javax.sql
mysql-conneter-java… 连接驱动(必须要导入)
实验环境搭建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CREATE TABLE users ( id INT PRIMARY KEY , `name` VARCHAR (40 ), `password` VARCHAR (40 ), email VARCHAR (60 ), birthday DATE ); INSERT INTO users (id ,`name` ,`password` ,email,birthday)VALUES (1 ,'张三' ,'123456' ,'zs@qq.com' ,'2000-01-01' );INSERT INTO users (id ,`name` ,`password` ,email,birthday)VALUES (2 ,'李四' ,'123456' ,'ls@qq.com' ,'2000-01-01' );INSERT INTO users (id ,`name` ,`password` ,email,birthday)VALUES (3 ,'王五' ,'123456' ,'ww@qq.com' ,'2000-01-01' );SELECT * FROM users ;
导入数据库依赖
1 2 3 4 5 6 <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.47</version > </dependency >
IDEA中连接数据库:
JDBC 固定步骤:
加载驱动
连接数据库,代表数据库
向数据库发送SQL的对象Statement : CRUD
编写SQL (根据业务,不同的SQL)
执行SQL
关闭连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class TestJdbc { public static void main (String[] args) throws ClassNotFoundException, SQLException { String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Class.forName("com.mysql.jdbc.Driver" ); Connection connection = DriverManager.getConnection(url, username, password); Statement statement = connection.createStatement(); String sql = "select * from users" ; ResultSet rs = statement.executeQuery(sql); while (rs.next()){ System.out.println("id=" +rs.getObject("id" )); System.out.println("name=" +rs.getObject("name" )); System.out.println("password=" +rs.getObject("password" )); System.out.println("email=" +rs.getObject("email" )); System.out.println("birthday=" +rs.getObject("birthday" )); } rs.close(); statement.close(); connection.close(); } }
预编译SQL (安全)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class TestJDBC2 { public static void main (String[] args) throws Exception { String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Class.forName("com.mysql.jdbc.Driver" ); Connection connection = DriverManager.getConnection(url, username, password); String sql = "insert into users(id, name, password, email, birthday) values (?,?,?,?,?);" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1 ,2 ); preparedStatement.setString(2 ,"狂神说Java" ); preparedStatement.setString(3 ,"123456" ); preparedStatement.setString(4 ,"24736743@qq.com" ); preparedStatement.setDate(5 ,new Date(new java.util.Date().getTime())); int i = preparedStatement.executeUpdate(); if (i>0 ){ System.out.println("插入成功@" ); } preparedStatement.close(); connection.close(); } }
事务
要么都成功,要么都失败!
ACID原则:保证数据的安全。
1 2 3 4 5 6 7 8 9 10 开启事务 事务提交 commit() 事务回滚 rollback() 关闭事务 转账: A:1000 B:1000 A(900 ) --100 --> B(1100 )
Junit单元测试
依赖
1 2 3 4 5 6 <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency >
简单使用
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!
1 2 3 4 @Test public void test () { System.out.println("Hello" ); }
失败的时候是红色:
搭建一个环境
1 2 3 4 5 6 7 8 9 CREATE TABLE account ( id INT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR (40 ), money FLOAT ); INSERT INTO account (`name` ,money) VALUES ('A' ,1000 );INSERT INTO account (`name` ,money) VALUES ('B' ,1000 );INSERT INTO account (`name` ,money) VALUES ('C' ,1000 );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 @Test public void test () { String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Connection connection = null ; try { Class.forName("com.mysql.jdbc.Driver" ); connection = DriverManager.getConnection(url, username, password); connection.setAutoCommit(false ); String sql = "update account set money = money-100 where name = 'A'" ; connection.prepareStatement(sql).executeUpdate(); String sql2 = "update account set money = money+100 where name = 'B'" ; connection.prepareStatement(sql2).executeUpdate(); connection.commit(); System.out.println("success" ); } catch (Exception e) { try { connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }