web开发:
web,网页
静态web
html、css
提供给人看到的数据不会发生变化
动态web
提供给人看到的数据会发生变化
在Java中,动态web资源开发的技术统称为JavaWeb
web应用程序:可以提供浏览器访问的程序
web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RCI1vcix-1620832381449)(JavaWeb.assets/image-20210103160241544.png)]
页面会动态显示:Web页面展示的效果因人而异
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oujMZWKX-1620832381452)(JavaWeb.assets/image-20210103161057957.png)]
缺点:
优点:
web页面可以动态更新,用户看到的界面不一样
它可以与数据库交互(数据持久化)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZaDDYiM-1620832381455)(JavaWeb.assets/image-20210103161506215.png)]
ASP:
PHP:
JSP/Servlet:
B/S:浏览器和服务器
C/S:客户端和服务器
…等等
服务器是一种被动操作,用来处理用户的一些请求和给用户一些响应信息
服务器:
IIS:
Tomcat:
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,他是最佳的选择。
Tomcat 实际上运行JSP 页面和Servlet。目前Tomcat最新版本为9.0.41。
工作3-5年之后,可以尝试手写Tomcat服务器
下载Tomcat:
Tomcat官网:https://tomcat.apache.org/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Te5ZPAXL-1620832381458)(JavaWeb.assets/image-20210103171112439.png)]
下载解压就OK!
文件夹的作用:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SzgVbtrG-1620832381460)(JavaWeb.assets/image-20210103171903705.png)]
启动、关闭Tomcat:在bin目录下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oWEaAGHd-1620832381461)(JavaWeb.assets/image-20210103172634599.png)]
连接访问测试:http://localhost:8080/
可能遇到的问题:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stV97bEU-1620832381463)(JavaWeb.assets/image-20210103173058316.png)]
可以配置启动的端口号:
Tomcat的默认端口号:8080
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
mysql端口号:3306
http端口号:80
https端口号:443
可以配置主机的名称:
默认的主机名:localhost–>127.0.0.1
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
网站默认存放的位置:webapps
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEdS7qCF-1620832381465)(JavaWeb.assets/image-20210103175722775.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gQB5R5Op-1620832381466)(JavaWeb.assets/image-20210103175741339.png)]
不会就先模仿:
将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹下(webapps),就可以访问。
网站应该有的结构:
--webapps:tomcat服务器下的web目录 -ROOT -delicious:网站的目录名 -WEB-INF -classes:Java程序 -lib:web应用所依赖的jar包 -web.xml:网站的配置文件 -index.html 默认的首页 -static -css -style.css -js -img -.....
HTTP协议:面试
Maven:构建工具
Servlet入门:
HTTP(超文本传输协议):是一个简单的请求-响应协议,他通常运行在TCP之上。
HTTPS:安全的
http1.0
http2.0
客户端——发请求(Request)——服务器
百度为例:
Request URL: https://www.baidu.com/ 请求地址 Request Method: GET get方法、post方法 Status Code: 200 OK 状态码:200 Remote(远程) Address: 14.215.177.38:443
Accept: text/html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Cache-Control: max-age=0 Connection: keep-alive
1、请求行
2、消息头
Accept:告诉浏览器,它所支持的数据类型 Accept-Encoding:支持那种编码格式 GBK、UTF-8、GB2312、ISO8859-1 Accept-Language:告诉浏览器,它的语言环境 Cache-Control:缓存控制 Connection:告诉浏览器,请求完成是断开连接还是保持连接 Host;主机 .......
服务器——响应——客户端
百度:
Cache-Control: private 缓存控制 Connection: keep-alive 连接 Content-Encoding: gzip 编码 Content-Type: text/html;charset=utf-8 类型
1、响应体:
Accept:告诉浏览器,它所支持的数据类型 Accept-Encoding:支持那种编码格式 GBK、UTF-8、GB2312、ISO8859-1 Accept-Language:告诉浏览器,它的语言环境 Cache-Control:缓存控制 Connection:告诉浏览器,请求完成是断开连接还是保持连接 Host;主机 Refresh:告诉客户端,多久刷新一次 Location:让网页重新定位
2、响应状态码:(重点)
200:请求响应成功(200)
3**:响应重定向
4**:找不到资源(404)
5**:服务器代码错误(500)(502–网关错误)
常见面试题:
当你在浏览器地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
答:在我们输入网址按下回车后,DNS服务器会通过当前网址解析这一网址的ip;在查找到IP之后,浏览器会向服务器发起一个tcp连接请求,此请求包含三次握手,如下:
第一次握手:建立链接时,客户端浏览器会发送syn包到服务器,并进入SYS_SENT状态,等待服务器的确认;第二次握手:服务器收到syn包后,必须确认客户端的syn,同时之间发送一个ack包,即是syn加ack包,此时服务器进入SYN_RECV状态,此时服务器被动打开后,接收到客户端的syn并且发送了ack时状态;第三次握手:客户端接收到服务器的syn+ack包后,给服务器发送确认包ack,包发送完毕之后,客户端和服务器端进入ESTABLISHED(tcp连接成功)状态,完成了第三次握手。
当三次握手结束后客户端和服务器端就建立好了连接,此时tcp协议断开,开始访问服务器下的默认index.html页面,并调用该访问的资源文件,展示相应的内容。
我们为什么要学习Maven工具(技术):
在javaweb开发中,需要使用大量的jar包,需要我们手动去导入
如何能够让一个工具帮我们导入和配置这个jar包
由此,Maven诞生了。
我们目前用来就是方便导入jar包
Maven的核心思想:约定大于配置————有约束就不要去违反
Maven会规定好你如何去编写我们的Java代码 ,我们必须遵循这个规范。
官网:https://maven.apache.org/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSHd508k-1620832381467)(JavaWeb.assets/image-20210104213140388.png)]
下载完成后,解压即可。
在我们的系统环境变量中配置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i9bXlMjm-1620832381468)(JavaWeb.assets/image-20210104215432599.png)]
测试Maven是否安装成功,保证必须配置完毕。
镜像:mirrors
国内建议使用阿里云镜像
<mirror> <id>nexus-aliyun</id> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf> </mirror>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IzqHIKi0-1620832381469)(JavaWeb.assets/image-20210104220602436.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rgy91wht-1620832381470)(JavaWeb.assets/image-20210104220522702.png)]
有本地仓库和远程仓库之分
建立一个本地仓库:localRepository
<localRepository>D:\DownLoad\apache-maven-3.6.3\maven-repo</localRepository>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQask8Va-1620832381471)(JavaWeb.assets/image-20210104220602436.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NGhSfn2b-1620832381472)(JavaWeb.assets/image-20210104221454182.png)]
启动IDEA
创建一个MavenWeb项目(使用Maven模板创建)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bIWyEuaW-1620832381473)(JavaWeb.assets/image-20210104224050625.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2LZxnDX-1620832381474)(JavaWeb.assets/image-20210104224524108.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aZgk9aMT-1620832381476)(JavaWeb.assets/image-20210104225222382.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CYRu1hQg-1620832381477)(JavaWeb.assets/image-20210104225302224.png)]
3、等待项目初始化完毕
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T7uhC3O6-1620832381478)(JavaWeb.assets/image-20210104230647628.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSxtHc1L-1620832381479)(JavaWeb.assets/image-20210104232936504.png)]
4、观察Maven仓库中多了什么?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BjEqvA7o-1620832381480)(JavaWeb.assets/image-20210104233218223.png)]
5、IDEA中的Maven设置
注意:IDEA项目创建成功后,看一眼Maven的配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ce8LP2vk-1620832381481)(JavaWeb.assets/image-20210104233910828.png)]
6、到这里,Maven在IDEA中的配置和使用就OK了!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZQ0DS8t-1620832381482)(JavaWeb.assets/image-20210104234831113.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gmhFobef-1620832381483)(JavaWeb.assets/image-20210104235546351.png)]
这个只有在web文件下才有!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMX244oI-1620832381484)(JavaWeb.assets/image-20210104235850311.png)]
一:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EUPxEB1z-1620832381486)(JavaWeb.assets/image-20210105000416560.png)]
二:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNN6d1FK-1620832381487)(JavaWeb.assets/image-20210105000814482.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xiYC1fp1-1620832381488)(JavaWeb.assets/image-20210105000950315.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mCdwZQHK-1620832381489)(JavaWeb.assets/image-20210105001451697.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hnQZ1zVx-1620832381490)(JavaWeb.assets/image-20210105001728572.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLWxtRZo-1620832381491)(JavaWeb.assets/image-20210105001941254.png)]
解决上述警告问题:
必须要配置:为什么会有这个问题:我们访问一个网站,需要指定文件夹的名字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZx6OdiU-1620832381492)(JavaWeb.assets/image-20210105002243652.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CrTWznKe-1620832381493)(JavaWeb.assets/image-20210105002944856.png)]
运行项目:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dZoGz5sK-1620832381494)(JavaWeb.assets/image-20210105011444552.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KbSuohO-1620832381495)(JavaWeb.assets/image-20210105011408524.png)]
pom.xml是Maven的核心配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qM1G1O45-1620832381496)(JavaWeb.assets/image-20210105012030877.png)]
<?xml version="1.0" encoding="UTF-8"?> <!--Maven版本和头文件--> <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> <!--这里是我们刚才配置的GAV--> <groupId>org.example</groupId> <artifactId>javaweb-01-maven</artifactId> <version>1.0-SNAPSHOT</version> <!--package:项目的打包方式 jar:Java应用 war:javaweb应用 --> <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> <!--具体依赖的jar包配置文件--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <!--项目构建用的东西--> <build> <finalName>javaweb-01-maven</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <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的高级之处在于它会帮你导入这个jar包所依赖的其他jar包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bFI5guwT-1620832381498)(JavaWeb.assets/image-20210105145024096.png)]
Maven由于它的约定大于配置,我们之后可能会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
<!--在build中配置resources,来防止我们资源导出失败的问题--> <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> </resource> </resources> </build>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKBluH8T-1620832381500)(JavaWeb.assets/image-20210105145423870.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecr7z6QV-1620832381501)(JavaWeb.assets/image-20210105145910956.png)]
Tomcat闪退
IDEA中每次都要重复配置Maven
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qkH3Csk7-1620832381502)(JavaWeb.assets/image-20210105151750195.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GX3DzjOi-1620832381503)(JavaWeb.assets/image-20210105151906886.png)]
Maven项目中Tomcat无法配置
Maven默认web项目中的web.xml版本问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sIQyDxRC-1620832381504)(JavaWeb.assets/image-20210105153156084.png)]
需要改为webapp4.0版本、和Tomcat的版本一致:复制Tomcat、ROOT中的web.xml配置到IDEA中的web.xml。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oV9zlwLa-1620832381506)(JavaWeb.assets/image-20210105153654435.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJLQMtjF-1620832381508)(JavaWeb.assets/image-20210105153937409.png)]
<?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>
5、Maven仓库的使用
地址:https://mvnrepository.com/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRnSba78-1620832381509)(JavaWeb.assets/image-20210105161925887.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IZdBmTBf-1620832381511)(JavaWeb.assets/image-20210105162043440.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jm4Ebqxi-1620832381513)(JavaWeb.assets/image-20210105162258528.png)]
把实现了Servlet接口的Java程序叫做:Servlet
Servlet接口在sun公司有两个默认的实现类:HttpServlet(常用)和GenericServlet
构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就是在这个项目里面建立Moudel,这个空的工程就是Maven的主工程;
关于Maven父子工程的理解:
父项目中会有
<modules> <module>servlet-01</module> </modules>
子项目中会有
<parent> <artifactId>javaweb-02-maven</artifactId> <groupId>org.example</groupId> <version>1.0-SNAPSHOT</version> </parent>
父项目中的Java,子项目可以直接使用
son extends father
Maven环境优化
修改web.xml为最新的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZ2tBQYB-1620832381514)(JavaWeb.assets/image-20210105235457758.png)]
将Maven的结构搭建完整
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nu24WDCV-1620832381515)(JavaWeb.assets/image-20210105235527507.png)]
编写一个Servlet程序
编写一个普通类
实现Servlet接口
public class helloServlet extends HttpServlet { //由于get或者post只是请求实现的不同方式,可以相互调用,业务逻辑都一样 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //ServletOutputStream outputStream = resp.getOutputStream(); PrintWriter writer = resp.getWriter(); //响应流 writer.print("Hello,Servlet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
编写Servlet映射
为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所有我们需要在web服务器中注册我们写的Servlet,还需要给它一个浏览器能够访问的路径;
<!--注册Servlet--> <servlet> <servlet-name>helloservlet</servlet-name> <servlet-class>com.chen.servlet.helloServlet</servlet-class> </servlet> <!--Servlet的请求路径--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
配置Tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIsvVmR2-1620832381515)(JavaWeb.assets/image-20210106002630209.png)]
注意:配置项目发布的路径就OK了。
启动测试
Servlet是由web服务器调用,web服务器在收到浏览器请求之后,会:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ii3I8VxR-1620832381516)(JavaWeb.assets/image-20210107180601023.png)]
一个Servlet可以指定一个映射路径
<!--Servlet的请求路径--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
一个Servlet可以指定多个映射路径
<!--Servlet的请求路径--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello4</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello5</url-pattern> </servlet-mapping>
一个Servlet可以指定通用映射路径
<!--Servlet的请求路径--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
默认请求路径
<!--Servlet的请求路径--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
指定一些后缀或者前缀等等…
<!--Servlet的请求路径--> <!--可以自定义后缀实现请求映射 注意点:*前面不能加项目映射的路径(/)--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>*.hello</url-pattern> </servlet-mapping>
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<!--注册Servlet--> <servlet> <servlet-name>helloservlet</servlet-name> <servlet-class>com.chen.servlet.HelloServlet</servlet-class> </servlet> <!--Servlet的请求路径--> <!--可以自定义后缀实现请求映射 注意点:*前面不能加项目映射的路径(/)--> <servlet-mapping> <servlet-name>helloservlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>errorservlet</servlet-name> <servlet-class>com.chen.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>errorservlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yw6uU5vC-1620832381517)(JavaWeb.assets/image-20210107195529604.png)]
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); System.out.println("Hello!"); //this.getInitParameter() 初始化参数 //this.getServletConfig() Servlet配置 //this.getServletContext() Servlet上下文 ServletContext servletContext = this.getServletContext(); String username = "陈永瑞"; //数据 servletContext.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username,值为:username } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); String username = (String) context.getAttribute("username"); resp.getWriter().print("名字:"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.chen.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>gets</servlet-name> <servlet-class>com.chen.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>gets</servlet-name> <url-pattern>/gets</url-pattern> </servlet-mapping>
然后就可以测试访问结果了。
<!--配置一些web初始化参数--> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().print(url);
<servlet> <servlet-name>gp</servlet-name> <servlet-class>com.chen.servlet.servletDemo</servlet-class> </servlet> <servlet-mapping> <servlet-name>gp</servlet-name> <url-pattern>/gp</url-pattern> </servlet-mapping>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入了servletDemo04"); ServletContext context = this.getServletContext(); //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径 //requestDispatcher.forward(req,resp); //调用forward方法实现请求转发 context.getRequestDispatcher("/gp").forward(req,resp);
<servlet> <servlet-name>sd4</servlet-name> <servlet-class>com.chen.servlet.servletDemo04</servlet-class> </servlet> <servlet-mapping> <servlet-name>sd4</servlet-name> <url-pattern>/sd4</url-pattern> </servlet-mapping>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7YQY57m-1620832381518)(JavaWeb.assets/image-20210107203053244.png)]
Properties
发现:两个目录下的properties都被打包到了同一路径下:我们俗称这个路径为classpath;
**思路:**需要一个文件流;
username = root01 password = 123456789
public class servletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream asStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/chen/servlet/db.properties"); Properties properties = new Properties(); properties.load(asStream); String username = properties.getProperty("username"); String password = properties.getProperty("password"); resp.getWriter().print(username+":"+password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
访问测试即OK!
响应
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,一个代表响应的HttpServletResponse;
简单分类:
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentLengthLong(long var1); void setContentType(String var1); void setDateHeader(String var1, long var2); void addDateHeader(String var1, long var2); void setHeader(String var1, String var2); void addHeader(String var1, String var2); void setIntHeader(String var1, int var2); void addIntHeader(String var1, int var2);
响应的状态码
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;
常见应用:
文件下载案例:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 要获取下载文件的路径 String realPath = "D:\\CYR File\\Java File\\javaweb-02-maven\\response\\target\\response\\WEB-INF\\classes\\陈永瑞.jpg"; System.out.println("下载文件的路径"+realPath); // 2. 下载的文件名是啥 String filename = realPath.substring(realPath.lastIndexOf("\\") + 1); // 3. 设置想办法让浏览器能够支持(Content-disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 resp.setHeader("Content-disposition","attachment;filename=" + URLEncoder.encode(filename,"UTF-8")); // 4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); // 5. 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; // 6. 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); // 7. 将FileOutputStream流写入到缓冲区(buffer);8. 使用OutputStream将缓冲区中的数据输出到客户端 while ((len=in.read(buffer))>0) { out.write(buffer,0,len); } in.close(); out.close(); }
验证码功能
验证码怎么来的?
前端实现(JS)
后端实现,需要用到Java的图片类,生产一张图片随机验证码
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_3BYTE_BGR); //得到图片 Graphics2D graphics = (Graphics2D) image.getGraphics(); //笔 //设置图片的背景颜色 graphics.setColor(Color.white); graphics.fillRect(0,0,80,20); //图片的形状 //给图片写数据 graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.BOLD,20)); graphics.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 { } }
<servlet> <servlet-name>ImageServlet</servlet-name> <servlet-class>com.chen.servlet.ImageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ImageServlet</servlet-name> <url-pattern>/img</url-pattern> </servlet-mapping>
实现重定向
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5xorTmKN-1620832381520)(JavaWeb.assets/image-20210110213054955.png)]
一个web资源(B)收到客户端请求后,他会通知客户端(A)去访问另外一个web资源(C),这个过程叫重定向。
常见场景:
用户登录
void sendRedirect(String var1) throws IOException;
测试:
public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* resp.setHeader("Location","/response_war/img"); resp.setStatus(302); */ resp.sendRedirect("/response_war/img"); //重定向 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
**面试题:**请你聊聊重定向和转发的区别?
相同点:
不同点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xxUbVRJB-1620832381520)(JavaWeb.assets/image-20210110215300786.png)]
上图:(1)图:请求转发; (2)图:重定向
重定向Demo:
public class RequestTest extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入这个请求了"); //处理请求 String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println(username+":"+password); //重定向的时候一定要注意路径问题,否则404; resp.sendRedirect("/r/success.jsp"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <h2>Hello World!</h2> <%--这里提交的路径,需要寻找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前的项目--%> <form action="${pageContext.request.contextPath}/login" method="get"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="提交"> </form> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>重定向跳转成功!</h1> </body> </html>
请求
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SqXYjXCP-1620832381521)(JavaWeb.assets/image-20210112162849378.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fedrnZiR-1620832381522)(JavaWeb.assets/image-20210112162937520.png)]
获取(前端的)参数和请求转发:
用getparameter等方法获取
parameter:获取单个
parameterValues:获取多个
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DAkcv2zV-1620832381523)(JavaWeb.assets/image-20210112163331471.png)]
public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.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("==============================="); System.out.println(req.getContextPath()); //输出(/r)当前路径 //通过请求转发 //这里的 / 代表当前的web应用(webapp) req.getRequestDispatcher("/success.jsp").forward(req,resp); resp.setCharacterEncoding("utf-8"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
**面试题:**请你聊聊重定向和转发的区别?
相同点:
不同点:
**会话:**用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。
**有状态会话:**一个同学来过教室,下次再来教室,我们就会知道这个同学曾经来过,这个过程称之为有状态会话。
eg:一个网站怎么证明你来过?
客户端 服务端
- 服务端给客户端一个 信件 ,客户端下次访问服务器带上信件就可以了;cookie
- 服务器登记你来过了,下次你来的时候我来匹配你;session
cookie:
session:
**常见场景:**网站登录之后,下次就不用在登录了,第二次访问直接就上去了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pPeM0uju-1620832381525)(JavaWeb.assets/image-20210114215635553.png)]
从请求中拿到cookie信息
服务器响应给客户端cookie
//获得cookie Cookie[] cookies = req.getCookies(); //这里返回数组,说明Cookie可能存在多个 //获得cookie中的key cookie.getName() //获得cookie中的值value cookie.getValue() //新建一个cookie new Cookie("lastLoginTime", System.currentTimeMillis() + ""); //设置cookie的有效期 //cookie有效期为一天 cookie.setMaxAge(24*60*60); //响应给客户端一个cookie resp.addCookie(cookie);
//保存用户上一次访问的时间 public class CookieDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //服务器告诉你来的时间,把这个时间封装成为一个 信件,你下次再来,我就知道你来了。 //解决中文乱码 req.setCharacterEncoding("utf-16"); resp.setCharacterEncoding("utf-16"); PrintWriter out = resp.getWriter(); //Cookie,服务器端从客户端获取。 Cookie[] cookies = req.getCookies(); //这里返回数组,说明Cookie可能存在多个 //判断Cookie是否存在 if(cookies != null ) { //如果存在怎么办 out.write("你上一次访问的时间是:"); /* for (Cookie cookie : cookies) { } */ 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有效期为一天 cookie.setMaxAge(24*60*60); resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
**cookie:**一般会保存在本地的 用户 目录下appdate;
**细节问题:**一个网站cookie是否存在上限?
删除Cookie:
不设置有效期,关闭浏览器自动失效;
设置有效期为 0 ;
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); } }
编码和解码:
//编码: URLEncoder.encode("陈永瑞","utf-8") //解码: URLDecoder.decode(cookie.getValue(),"utf-8")
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WOsJzrHp-1620832381526)(JavaWeb.assets/image-20210114215837160.png)]
什么时Session:
服务器会给每个用户(浏览器)创建一个Session对象;
一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就一直存在;
用户登录之后,整个网站的其他页面都能访问 ——> 保存用户的信息、保存购物车的信息…
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyZlaqHm-1620832381527)(JavaWeb.assets/image-20210114204053332.png)]
Session和Cookie的区别:
使用场景:
使用Session:
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"); //得到Session HttpSession session = req.getSession(); //给Session中存数据 session.setAttribute("name",new Person("陈永瑞",23)); //获取Session的ID String sessionId = session.getId(); //判断session是不是新创建的 if (session.isNew()){ resp.getWriter().write("session创建成功!,ID:"+sessionId); }else { resp.getWriter().write("session已经在服务器里创建了!,ID:"+sessionId); } //Session创建的时候做了什么事情 Cookie cookie = new Cookie("JSESSIONID",sessionId); resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } public class SessionDemo02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html; charset=utf-8"); //得到Session HttpSession session = req.getSession(); Person Person = (Person) session.getAttribute("name"); System.out.println(Person); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } public class SessionDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.removeAttribute("name"); //手动注销Session session.invalidate(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
**会话(Session对象)自动过期:**web.xml中配置
<!--设置Session默认的生效时间--> <session-config> <!--15分钟后自动失效,以分钟为单位--> <session-timeout>15</session-timeout> </session-config>
Java Servlet Pages:Java服务器端页面,也和Servlet一样用于开发动态web页面;
最大的特点:
思路:JSP到底怎么执行的?
代码层面没有任何问题;
服务器内部工作
Tomcat中有一个work目录
IDEA中使用Tomcat的会在IDEA的Tomcat中生出一个work目录;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NvVrlfnT-1620832381529)(JavaWeb.assets/image-20210114221353890.png)]
我的电脑地址:C:\Users\24937.IntelliJIdea2019.3\system\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\cookie\org\apache\jsp
发现JSP文件页面转变成了Java程序:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lQqFOc1Z-1620832381530)(JavaWeb.assets/image-20210114221737693.png)]
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet。
JSP最终也会被转换为一个Java类!
JSP本质上就是一个Servlet:
//初始化 public void _jspInit() { } //销毁 public void _jspDestroy() { } //JSPService public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)throws java.io.IOException, javax.servlet.ServletException { }
判断请求
内置了一些对象
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; //响应
输出页面前增加的一些代码
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;
以上的这些个对象我们可以在JSP页面中直接使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-If2Jlbq1-1620832381532)(JavaWeb.assets/image-20210114224445784.png)]
在JSP页面中:
只要是Java代码就会原封不动的输出;
out.print(name);
如果是HTML代码就会转化为:
out.write("<html>\n"); out.write("<body>\n"); out.write("<h2>Hello World!</h2>\n"); out.write("</body>\n"); out.write("</html>\n");
以这样的格式输出到前端
需要的依赖:
<dependencies> <!--Servlet 依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!--JSP 依赖--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> <!--JSTL 表达式的依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--standard 标签库--> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies>
任何语言都有自己的语法,Java中有,JSP作为Java技术的一种应用,也有属于自己的一些语法;(Java中的语法都支持)
<%--JSP表达式 作用:用来将程序输出,输出到客户端 格式:<%= 变量或者表达式%> --%> <%= new java.util.Date()%>
格式:<% 代码块 %> <%--JSP脚本片段--%> <% int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } out.println("<h1>Sum="+sum+"</h1>"); %>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rFPHcUtA-1620832381533)(JavaWeb.assets/image-20210116221106450.png)]
格式:<% 代码块 %> <% int i=10; out.println(i); %> <p>这是一个JSP文档</p> <% int j=10; out.println(j); %> <br> <%--在代码中嵌入HTML--%> <% for (int k = 0; k < 3; k++) { %> <p>嗨,我分成两部分了。<%= k%></p> <% } %>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RC9xFIsE-1620832381535)(JavaWeb.assets/image-20210116222254289.png)]
格式:<%! 代码块 %> <%! static { System.out.println("Loading Servlet!"); } private int globalVAr = 0; private void chen(){ System.out.println("进入了方法chen!"); } %>
注意:jsp声明会被编译到JSP生成的Java类中;而其他的,会被生成到_jspService方法中!
在jsp中嵌入Java代码即可!
<%-- --%> 注释 <% %> 脚本片段 <%= %> 表达式 <%! %> 声明变量
JSP的注释不会在客户端显示,HTML的会在客户端显示。
**定制错误页面:**404、500等 eg:掌上天软的服务器开小差一样
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <%--定制错误页面--%> <%@ page errorPage="error/500.jsp" %> <head> <title>Title</title> </head> <body> <% int x = 1/0; %> </body> </html>
或者在web.xml里面配置:
<error-page> <error-code>500</error-code> <location>/error/500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page>
一个网站的头部导航栏和底部版本商家信息等,每个页面都一样:
<%@ page ... %> <%@ include file=" "%> <%--<%@ include file:会将页面合二为一,本质为一个页面--%> <%@ include file="common/header.jsp"%> <h1>网页主体!</h1> <%@ include file="common/footer.jsp"%> <br> <%--JSP标签 <jsp:include page:拼接页面,本质还是三个页面,推荐用这个,灵活性更强--%> <jsp:include page="common/header.jsp" <h1>网页主体!</h1> <jsp:include page="common/footer.jsp"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-97vCv1DI-1620832381536)(JavaWeb.assets/image-20210116233529660.png)]
一个项目的基本文件夹分类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gAhJrbb-1620832381538)(JavaWeb.assets/image-20210116233615442.png)]
<%--内置对象--%> <% pageContext.setAttribute("name1","陈永瑞1"); //保存的数据只在一个页面有效 request.setAttribute("name2","陈永瑞2"); //保存的数据只在一次请求中有效,请求转发也会携带宰割数据 session.setAttribute("name3","陈永瑞3"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器 application.setAttribute("name4","陈永瑞4");//保存的数据只在服务器中有效,从打开服务器到关闭服务器 %>
<%--内置对象--%> <% pageContext.setAttribute("name1","陈永瑞1"); //保存的数据只在一个页面有效 request.setAttribute("name2","陈永瑞2"); //保存的数据只在一次请求中有效,请求转发也会携带宰割数据 session.setAttribute("name3","陈永瑞3"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器 application.setAttribute("name4","陈永瑞4"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器 %> <%--脚本片段中的代码,会被原封不动的生成到JSP.java 要求:这里面的代码必须保证Java语法的正确性 --%> <% //从pageContext取出,我们通过寻找的方式来取出 //从底层到高层(作用域):pageContext->request->session->application String name1 = (String) pageContext.findAttribute("name1"); String name2 = (String) pageContext.findAttribute("name2"); String name3 = (String) pageContext.findAttribute("name3"); String name4 = (String) pageContext.findAttribute("name4"); String name5 = (String) pageContext.findAttribute("name5"); //不存在 %> <%--使用EL表达式输出:${}--%> <h1>去除的值为:</h1> <h1>${name1}</h1> <h1>${name2}</h1> <h1>${name3}</h1> <h1>${name4}</h1> <h1>${name5}</h1> <%--EL表达式--%> <h1><%= name5%></h1> <%--jsp表达式--%>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k01sxK78-1620832381540)(JavaWeb.assets/image-20210117164325235.png)]
request:客户端向服务器发送请求,产生的数据,用户看完就没用了;eg:新闻、用户看完就没用的;
session:客户端向服务器发送请求,产生的数据,用户看完一会还有用;eg:购物车;
Application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用;eg:聊天记录;
从底层到高层(作用域):pageContext->request->session->application
<!--JSTL 表达式的依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--standard 标签库--> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
EL表达式:${ }
JSP标签:
<h1>1</h1> <%--<jsp:include page=""--%> <%--http://localhost:8080/jsp/jsptag1.jsp?name=cyr&age=22--%> <jsp:forward page="jsptag2.jsp"> <jsp:param name="name" value="陈永瑞"/> <jsp:param name="age" value="22"/> </jsp:forward>
<h1>2</h1> <%--取出参数--%> 名字:<%= request.getParameter("name")%> 年龄:<%= request.getParameter("age")%>
JSTL表达式:
JSTL标签:就是为了弥补HTML标签的不足;它自定义了许多标签供我们使用,标签的功能和Java代码一样!
格式化标签
SQL标签
xml标签
核心标签(掌握部分)
核心标签是最常用的 JSTL标签。引用核心标签库的语法如下:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
标签:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yo9jHwmo-1620832381542)(JavaWeb.assets/image-20210117173253423.png)]
JSTL标签库使用步骤:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入JSTL核心标签库,我们才能使用JSTL核心标签库--%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> </body> </html>
c:if
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入JSTL核心标签库,我们才能使用JSTL核心标签库--%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <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> </html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oavOd4O9-1620832381543)(JavaWeb.assets/image-20210117220630733.png)]
c:set、c:choose、c:when
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入JSTL核心标签库,我们才能使用JSTL核心标签库--%> <%@ 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 >= 70}"> 你的成绩为一般! </c:when> <c:when test="${score >= 60}"> 你的成绩为合格! </c:when> <c:when test="${score < 60}"> 你的成绩为不合格! </c:when> </c:choose> </body> </html>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcSfKg0o-1620832381545)(JavaWeb.assets/image-20210117220649132.png)]
c:forEach、c:out
<%@ page import="java.util.ArrayList" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%--引入JSTL核心标签库,我们才能使用JSTL核心标签库--%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <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>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ICKrihBj-1620832381546)(JavaWeb.assets/image-20210117225008268.png)]
JavaBean是实体类
JavaBean有特殊的写法:
一般用来和数据库的字段做映射 ORM
ORM:对象关系映射
数据库 | JavaBean |
---|---|
表 | 类 |
字段 | 属性 |
行记录 | 对象 |
eg:对应关系:
people表
id | name | age | address |
---|---|---|---|
1 | 陈永瑞1号 | 22 | 北京 |
2 | 陈永瑞2号 | 23 | 西安 |
3 | 陈永瑞3号 | 24 | 云南 |
class People{ private int id; private String name; private int age; private String address; } class A{ new People(1,"陈永瑞1号",22,"北京"); new People(2,"陈永瑞2号",23,"西安"); new People(3,"陈永瑞3号",24,"云南"); }
什么是MVC:Model View Controller (模型(数据库字段) 视图(JSP) 控制器(Servle))
Servlet和JSP都可以写Java代码:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TW3Fp7Zs-1620832381548)(JavaWeb.assets/image-20210126205143390.png)]
用户直接访问控制层,控制层就可以直接操作数据库;
Servlet——>增删改查(CRUD)——>数据库
弊端:程序十分臃肿,不利于维护;
Servlet代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码;
架构:没有什么是加一层解决不了的!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZFbgCSi-1620832381549)(JavaWeb.assets/image-20210126210104912.png)]
Mode:
View:
Controller:(Servlet)
eg:
登录——>接受用户的登录请求——>处理用户的请求(获取用户的参数:username、password…)——>交给业务层处理登录业务(判断用户名密码是否正确:事物)——>Dao层查询用户名和密码是否正确——>数据库
Filter:过滤器——>用来过滤网站的数据;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pp81RaR4-1620832381550)(JavaWeb.assets/image-20210126211700033.png)]
Filter开发步骤:
导包
编写过滤器
导包不要错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51qSSEJc-1620832381551)(JavaWeb.assets/image-20210126213713750.png)]
实现Filter接口,重写对应的方法:
public class CharacterEncodingFilter implements Filter { //初始化 public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化"); } //Chain:链的意思 /* 1.过滤中的所有代码,在过滤特定请求的时候都会执行 2.必须要让过滤器继续通行 3.filterChain.doFilter(servletRequest,servletResponse);这句话是固定的,必须要写。 */ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=UTF-8"); System.out.println("CharacterEncodingFilter执行前..."); filterChain.doFilter(servletRequest,servletResponse);//让我们请求继续走,如果不写,程序到这里就被拦截停止了! System.out.println("CharacterEncodingFilter执行后..."); } //销毁:web服务器关闭的时候,过滤器会销毁。 public void destroy() { System.out.println("CharacterEncodingFilter销毁"); } }
在web.xml中配置Filter:(同Servlet一致)
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.chen.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <!--只要是 /servlet 下的任何请求,都会经过这个过滤器--> <url-pattern>/servlet/*</url-pattern> <!--整个网站都要经过这个过滤器 <url-pattern>/*</url-pattern>--> </filter-mapping>
监听器:就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
实现监听器的接口有n种:
编写一个监听器
实现监听器的接口…
//统计网站在线人数:统计Session public class OnlineCountListener implements HttpSessionListener { //创建Session监听:看你的一举一动 //一旦创建Session就会触发一次这个事件! public void sessionCreated(HttpSessionEvent httpSessionEvent) { ServletContext context = httpSessionEvent.getSession().getServletContext(); Integer onlineCount = (Integer) context.getAttribute("OnlineCount"); if (onlineCount == null){ onlineCount = new Integer(1); }else { int count = onlineCount.intValue(); onlineCount = new Integer(count+1); } context.setAttribute("OnlineCount",onlineCount); } //销毁Session监听 //一旦销毁Session就会触发一次这个事件! public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { ServletContext context = httpSessionEvent.getSession().getServletContext(); Integer onlineCount = (Integer) context.getAttribute("OnlineCount"); if (onlineCount == null){ onlineCount = new Integer(0); }else { //转换为int类型的进行+1 int count = onlineCount.intValue(); onlineCount = new Integer(count-1); } context.setAttribute("OnlineCount",onlineCount); } } /* Session销毁: 1.手动销毁 getSession().invalidate(); 2.自动销毁 在web.xml中配置 */
在web.xml中注册监听器
<!--注册监听器--> <listener> <listener-class>com.chen.listener.OnlineCountListener</listener-class> </listener>
监听器的销毁
手动销毁 getSession().invalidate();
自动销毁 在web.xml中配置
<!--自动销毁--> <session-config> <!--设置1分钟后自动销毁--> <session-timeout>1</session-timeout> </session-config>
看情况是否使用
监听器:GUI编程中经常使用
public class TestPanel { public static void main(String[] args) { Frame frame = new Frame("中秋节快乐"); //新建一个窗体 Panel panel = new Panel(null); //面板 frame.setLayout(null); //设置窗体的布局 frame.setBounds(300,300,500,500); frame.setBackground(new Color(0,0,255)); //设置背景颜色 panel.setBounds(200,200,300,300); panel.setBackground(new Color(0,255,0)); //设置背景颜色 frame.add(panel); frame.setVisible(true); //不设置关闭,图形界面是关闭不了的 //监听事件,监听关闭事件 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { super.windowClosing(e); System.exit(0); } }); } }
用户登录之后才能进入主页!用户注销后就不能进入主页了!——采用过滤器
用户登录之后,向Session中放入用户的数据;
进入主页的时候要判断用户是否已近登录;
要求:在过滤器中实现;
public class SysFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { //ServletRequest HttpServletRequest HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; if (request.getSession().getAttribute(Constant.USER_SESSION) == null){ response.sendRedirect("/error.jsp"); } filterChain.doFilter(req,resp); } public void destroy() { } }
什么是JDBC:Java连接数据库!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gFKZSw0j-1620832381552)(JavaWeb.assets/image-20210221150831843.png)]
需要Jar包的支持:
实验环境搭建:
先创建数据库表单;
导入数据库依赖;
<dependencies> <!--mysql的驱动(必须导入)--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> </dependencies>
IDEA中连接数据库;
IDBC固定步骤:
public class TestJdbc { public static void main(String[] args) throws ClassNotFoundException, SQLException { //配置用户信息和url //useUnicode=true&characterEncoding=utf8&useSSL=true(1.支持中文编码 2.设置字符集为utf8 3.使用安全连接) String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false"; String username = "root"; String password = "199819"; //1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //固定写法 //2.连接数据库 Connection代表数据库 Connection connection = DriverManager.getConnection(url,username,password); //3.向数据库发送SQL的对象Statement : CRUD(增删改查) Statement statement = connection.createStatement(); //4.编写SQL语句 String sql = "SELECT * FROM users;"; //5.执行查询SQL语句,返回一个ResultSet:结果集 ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()){ System.out.println("id=" + resultSet.getObject("id")); System.out.println("name=" + resultSet.getObject("name")); System.out.println("password=" + resultSet.getObject("password")); System.out.println("email=" + resultSet.getObject("email")); System.out.println("birthday=" + resultSet.getObject("birthday")); } //6.关闭连接,释放资源(一定要做,先开后关) resultSet.close(); statement.close(); connection.close(); } }
预编译SQL写法:
public class TestJdbc2 { public static void main(String[] args) throws SQLException, ClassNotFoundException { //配置用户信息和url //useUnicode=true&characterEncoding=utf8&useSSL=true(1.支持中文编码 2.设置字符集为utf8 3.使用安全连接) String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false"; String username = "root"; String password = "199819"; //1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //固定写法 //2.连接数据库 Connection代表数据库 Connection connection = DriverManager.getConnection(url,username,password); //3.编写SQL String sql = "insert into users(id, name, password, email, birthday) value (?,?,?,?,?);"; //4.预编译 PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,4); //给第一个占位符?的值赋值为4; preparedStatement.setString(2,"狂神说Java"); //给第二个占位符?的值赋值为狂神说Java; preparedStatement.setString(3,"123456"); //给第三个占位符?的值赋值为123456; preparedStatement.setString(4,"123456@qq.com"); //给第四个占位符?的值赋值为123456@qq.com; preparedStatement.setDate(5,new Date(new java.util.Date().getTime())); //给第五个占位符?的值赋值为new Date(new java.util.Date().getTime()); //5.执行SQL,返回受影响的行数 int i = preparedStatement.executeUpdate(); if (i > 0){ System.out.println("插入成功!"); } //6.关闭连接,释放资源(一定要做,先开后关) preparedStatement.close(); connection.close(); } }
事物:
要么都成功、要么都失败!
ACID原则:保证数据的安全。
开启事物 事物提交 commit() 事物回滚 rollback() 关闭事物 eg: 转账: A:1000 B:1000 A 转 B 100元:A(900)——100——>B(1100)
junit单元测试
依赖:
<!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency>
简单使用:
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!
public class TestJdbc3 { @Test public void test(){ System.out.println("hello"); } }
整体:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FIblRlo8-1620832381553)(image/image-20210403154857377.png)]
数据库:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hiVbKBpD-1620832381554)(image/image-20210403155039792.png)]
搭建一个mavenweb项目
配置tomcat
测试maven项目能不能跑起来
导入项目中会遇到的jar包
jsp、servlet、mysql驱动、jstl、stand。。。
创建项目包结构
编写实体类
ORM映射:表和类一一对应
编写基础公共类
数据库配置文件
#连接数据库的4个属性 driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf8 username=root password=199819
gs) throws SQLException, ClassNotFoundException {
//配置用户信息和url
//useUnicode=true&characterEncoding=utf8&useSSL=true(1.支持中文编码 2.设置字符集为utf8 3.使用安全连接)
String url = “jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8&useSSL=false”;
String username = “root”;
String password = “199819”;
//1.加载驱动 Class.forName("com.mysql.jdbc.Driver"); //固定写法 //2.连接数据库 Connection代表数据库 Connection connection = DriverManager.getConnection(url,username,password); //3.编写SQL String sql = "insert into users(id, name, password, email, birthday) value (?,?,?,?,?);"; //4.预编译 PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1,4); //给第一个占位符?的值赋值为4; preparedStatement.setString(2,"狂神说Java"); //给第二个占位符?的值赋值为狂神说Java; preparedStatement.setString(3,"123456"); //给第三个占位符?的值赋值为123456; preparedStatement.setString(4,"123456@qq.com"); //给第四个占位符?的值赋值为123456@qq.com; preparedStatement.setDate(5,new Date(new java.util.Date().getTime())); //给第五个占位符?的值赋值为new Date(new java.util.Date().getTime()); //5.执行SQL,返回受影响的行数 int i = preparedStatement.executeUpdate(); if (i > 0){ System.out.println("插入成功!"); } //6.关闭连接,释放资源(一定要做,先开后关) preparedStatement.close(); connection.close(); }
}
**事物:** 要么都成功、要么都失败! ACID原则:保证数据的安全。 ```java 开启事物 事物提交 commit() 事物回滚 rollback() 关闭事物 eg: 转账: A:1000 B:1000 A 转 B 100元:A(900)——100——>B(1100)
junit单元测试
依赖:
<!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>compile</scope> </dependency>
简单使用:
@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行!
public class TestJdbc3 { @Test public void test(){ System.out.println("hello"); } }
整体:
[外链图片转存中…(img-FIblRlo8-1620832381553)]
数据库:
[外链图片转存中…(img-hiVbKBpD-1620832381554)]
搭建一个mavenweb项目
配置tomcat
测试maven项目能不能跑起来
导入项目中会遇到的jar包
jsp、servlet、mysql驱动、jstl、stand。。。
创建项目包结构
编写实体类
ORM映射:表和类一一对应
编写基础公共类
数据库配置文件
#连接数据库的4个属性 driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=utf8 username=root password=199819