JavaWeb
将javaweb可以分为两种
1.java
2.web
1.web基本的概念
1.1web开发:
web 网页的意思。可以将web分为两种
-
静态web
- html ,css
- 动静态web存在的缺点
- web页面无法动态更新,所有的用户看到的都是同一个页面
- 它无法和数据库交互(数据无法持久化,用户无法交互,注册,商品信息,用户信息等等)
-
动态web
提供给所有人看的数据始终发生变化的,每个人在不同的时间,不同的地点看到的信息各不相同。页面会动态显示“web的页面展示的效果因人而异”
- 几乎所有的网站
在java中,动态web资源开发的技术统称为javaweb
缺点 :
-
加入服务器的动态web资源出现错误,我们需要重新编写我们的后台程序,重新发布
- 停机维护
优点:
-
web页面可以动态分更新,每个用户看见的是不同的页面
-
它可以与数据库进行交互(数据持久化的,用户可以交互)
1.2web应用程序
可以提供浏览器访问的程序
一个web应用由多部分组成(静态web,动态web)
- html,css
- jsp,servlet
- java程序
- jar包
- 配置文件(properties)
web应用程序编写完成后,若要提供给外界访问,需要一个服务器来统一管理。
2.web服务器
2.1架构:
B/S:浏览和服务器
C/S:客户端和服务器
2.2技术讲解:
ASP
- 微软:国内最早流行的就是Asp
- 在HTML中嵌入VB的脚本,ASP+COM
- 在ASP开发中,基本一个页面会有几千行的业务代码,业务极其混乱
- 页面混乱,维护成本高
PHP
- PHP 开发进度很快,功能很强大,跨平台,代码很简单
- 无法承载大访问量的情况(这是局限性)
JSP/Servlet
- sun公司主推的B/S架构
- 基于java语言的
- 可以承载三高(高并发,高可用,高性能)问题带来的影响、
- 语法非常像asp asp---->jsp 加强市场的强度
2.3Web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户的一些信息
IIS:
微软的:ASP,微软的一些自带。
Tomcat:
Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,最新的Servlet和Jsp规范总能在Tomcatzhong得到体现,因为Tomcat技术先进,性能稳定,而且免费。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。
(摘自百度)
jetty:
jetty是一个开源的servlet容器,它是基于java的web容器,相对于tomcat而言,jetty更轻量级
下载tomcat
- 安装or解压
- 了解配置文件及目录结构
- 这个东西的作用
3.Tomcat
3.1安装tomcat
1.下载tomcat
官网: http://tomcat.apache.org/
2.解压tomcat
3.启动、关闭tomcat
4.访问测试
- 先启动tomcat
- 访问: http://localhost:8080/
测试可能遇到的问题:
- Java环境变量没有配置正确
- 闪退问题:需要配置兼容性
- 乱码问题:配置文件中设置
5.配置
配置文件中可以配置:
-
配置主机的名称
主机的名称默认是:localhost = 127.0.0.1
默认网站应存放的位置为:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
- x配置tomcat的端口号
- tomcat的默认的端口号是8080
- mysql的默认端口号是3306
- http的默认的端口号是80
- https的默认的端口号是443
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
3.2使用tomcat发布一个网站的
将自己写的网站放在服务器(tomcat)上指定的web应用的文件夹(webapps)下,就可以访问了
一个网站应该有的目录结构
--webapps
--root
--WEB-INF
--web.xml 网站的配置文件
--classes java程序
--lib web应用所依赖的jar包
--index.html默认的首页
--static
--css
--js
--img
-.....
4.高难度面试题,网站是如何进行访问的
一个网站访问的流程:
1.输入一个域名:回车
2.先在本机目录C:\Windows\System32\drivers\etc\hosts
配置文件下找有没有这个域名的映射:
-
如果有这个域名的映射,就直接返回对应的ip地址,在这个地址中有我们需要访问的web程序,就可以直接访问
127.0.0.1 localhost
-
如果没有,就去DNS服务器找,找到就返回,找不到就返回找不到
5.HTTP
5.1什么是HTTP
HTTP(超文本传输协议)是一个简单的请求-响应协议,他通常是运行在TCP之上。
- 文本:html,字符串,~…
- 超文本:图片,音乐,视频,定位,地图…
- http的端口号是80
HTTPS:是安全的
- 端口号是443
5.2HTTP的两个时代
- http 1.0
- HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接。
- http2.0
- HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源
5.3HTTP请求
客户端---->发送请求(request)—>服务器
百度:
Request URL: https://www.baidu.com/tn=62095104_26_oem_dg //请求的地址
Request Method: GET //请求的方式get/post
Status Code: 200 OK //状态码:200 成功
Remote(远程) Address: 182.61.200.6: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
5.3.1请求行
- 请求行中的请求方式:get
- 请求方式分为get,post,head,delete…
- get:请求能过携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
- post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏中显示数据内容,安全,但不高效。
5.3.2消息头
Accept: 告诉浏览器它所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK.utf-8
Accept-Language: 告诉浏览器它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器 ,请求完成是断开还是保持连接
HOST:主机....
5.4HTTP响应
服务器—>响应(response)—>客户端
百度:
Cache-Control:private 缓存控制
Connection:Keep-Alive 连接
Content-Encoding:gzip 编码
Content-Type:text/html 类型
5.4.1响应体
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;
5.4.2响应状态吗
200:请求响应成功 200
3xx:请求重定向
- 重定向:你重新到我给你的新位置去
4xx:找不到资源 404
- 资源不存在
5xx:服务器代码错误 500 502:网关错误
6.面试题
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
- 域名的解析
- 发起TCP的三次握手
- 建立TCP连接后发起http请求
- 服务器响应http请求浏览器得到html代码
- 浏览器解析html代码,并请求html代码中的资源(js,css,图片)
- 浏览器对页面进行渲染呈现给用户
7.Maven
7.1为什么要学习maven
- 在javaweb开发中,我们要使用大量的jar包,我们需要手动去导入
- maven可以帮我们自动的导入和配置jar包
7.2maven项目架构管理工具
我们现在使用maven目的是方便导入jar包
Maven的核心思想:约定大于配置
- 有约束,不要去违反
7.3下载maven
官网:http://maven.apache.org/
下载完成后,解压即可!
7.4环境变量配置
在系统环境变量中配置以下配置:
- M2_HOME maven目录下的bin目录 E:\javaenvironment\maven\bin
- MAVEN_HOME maven目录下E:\javaenvironment\maven
- 在系统的path目录下配置 %MAVEN_HOME%\bin
配置完成后使用cmd进行测试。mvn -version
7.5阿里云镜像
打开配置文件settings.xml
- 镜像:mirrors
- 作用:加速我们的下载
- 国内建议使用阿里云镜像
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
7.6本地仓库
建立一个本地仓库:localRepository
<localRepository>E:\javaenvironment\maven\maven-repo</localRepository>
7.7在IDEA中使用maven
7.7.1 启动IDEA
7.7.2 创建一个mavenweb项目
7.7.3 观察maven的本地仓库
本地仓库多了很多的文件
7.7.4 IDEA中的maven设置
7.8创建一个普通的maven项目
这些只有在web下才会有的
7.9标记文件夹功能
7.9.1 第一种标记方式
7.9.2 第二种标记方式
通过点击来标记:
7.10在IDEA中配置tomcat
添加artifacts
必须要的配置:我们在访问一个网站时必须要指定一个文件夹
启动tomcat
7.11 pom.xml
<?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>com.mahui</groupId>
<artifactId>javaweb-maven01</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--package:项目打包方式
jar:java应用
war:javaweb应用
-->
<name>javaweb-maven01 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<!--配置-->
<properties>
<!--项目默认的构建编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--编码的版本-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</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-maven01</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由于它的约定大于配置,我们之后可能遇到我们的配置文件无法被导出或者生效的问题:
解决方案:
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<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>
7.12IDEA中maven的jar联系关系图
8. servlet
8.1什么是servlet
- Servlet是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需完成两个步骤
- 编写一个类,实现Servlet接口
- 把开发好的java类部署到web服务器中
把实现了Servlet接口的java程序叫做Servlet
8.2HelloServlet
Servlet接口sun公司有两个默认的实现类:HttpServlet,
GenericServlet
-
构建一个普通的maven项目,删除里边的src目录,在这个项目里建立Moudel,这个空的工程就是Maven的主工程
-
关于Maven父子工程的理解
-
父项目中会有
<modules> <module>servlet-01</module> </modules>
-
子项目中会有
<parent> <artifactId>java-01-servlet</artifactId> <groupId>com.mahui</groupId> <version>1.0-SNAPSHOT</version> </parent>
-
父项目中的jar包在子项目中可以直接使用
son extends father
-
-
Maven 环境优化
- 修改web.xml为最新的
- 将maven的结构构建完整
-
编写一个Servlet程序
-
编写一个普通的类
-
实现Servlet接口,这里我们可以直接继承HttpServlet
package com.mahui.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { //由于get和post只是不同的请求方式,所以他们两个可以互相调用,业务逻辑都是一样的 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入了doget方法"); PrintWriter writer = resp.getWriter(); writer.print("hello ,servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
编写servlet映射
为什么要需要映射:我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的servlet,还需要给它一个浏览器能够访问的路径
<!--注册servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.mahui.servlet.HelloServlet</servlet-class> </servlet> <!--servlet请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
配置tomcat
-
启动测试
8.3Servlet原理
8.4Mapping问题
8.4.1一个Servlet可以指定一个映射路径
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
8.4.2一个Servlet可以指定多个映射路径
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<!--servlet请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
8.4.3一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
8.4.4默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
8.4.5制定一些后缀或者前缀等等
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
hello/sajdlkajda.qinjiang
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.ma</url-pattern>
</servlet-mapping>
8.4.6优先级问题
指定固有的映射路径优先级最高,如果找不到会走默认的请求处理
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.mahui.servlet.Error</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
8.5ServletContext
web容器在启动的时候,它会为每一个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
8.5.1共享数据
在一个servlet中保存的数据可以在另外一个servlet中拿到:
在helloservlet中保存数据
package com.mahui.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getServletConfig(); Servlet 配置
// this.getInitParameter(); Servlet 初始化参数
//this.getServletContext(); Servlet 上下文
ServletContext context =this.getServletContext();
String username="张三";
//将一个数据保存在servletcontext中,名字为:username 值为:username
context.setAttribute("username",username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.在GetServlet中获得数据
package com.mahui.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//context是全局的,唯一的,凌驾于servlet之上
ServletContext context =this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
writer.print("姓名:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml中注册:
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.mahui.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.mahui.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
测试过程:
web程序启动后,如果先访问/getc,则页面显示为null
访问/hello之后,在访问/getc才能获得数据。
8.5.2 获取初始化参数
配置初始化参数
在web.xml中配置
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
获取初始化参数
package com.mahui.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GetParam extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过context来获得初始化参数
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
PrintWriter writer = resp.getWriter();
writer.print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.5.3请求转发
package com.mahui.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestDispatcher extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了RequestDispatcher");
context.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
请求转发和请求重定向的区别
A想要拿个东西,但是在c那,a不知道,a先找b
请求转发:
a通过b让b从c那拿到,并通过b响应给啊
请求重定向
a从b那知道在c那,然后a自己去c那拿
8.5.4读取资源文件
db.properties文件在target中的位置
package com.mahui.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String user = properties.getProperty("username");
String pwd = properties.getProperty("password");
PrintWriter writer = resp.getWriter();
writer.print(user+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.6HttpServletResponse
web服务器在接收到客户端的请求时,会针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse
- 获得客户端请求过来的参数:HttpServletRequest
- 获得给客户端响应的一些信息:Http Servlet Response
8.6.1 简单分类
1.负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
2.负责向浏览器发送响应头的方法
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);
3.响应的状态码
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;
8.6.2 下载文件
1.向浏览器输出消息
2.下载文件
- 要获取下载文件的路径
- 下载文件名是啥?
- 设置想办法让浏览器能够支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutPutStream对象
- 将FileOutStream流写入到buffer缓冲区
- 使用OutOutStream将缓冲区的数据输出到客户端!
package com.mahui.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
public class FileResponse extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 要获取下载文件的路径
String realPath = "E:\\IntelliJIDEA\\fuxilianxi\\javaweb-servlet-04\\response\\target\\classes\\1.jpg";
// 2. 下载文件名是啥?
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
// 3. 设置想办法让浏览器能够支持下载我们需要的东西
resp.setHeader("Content-Disposition", "attachment;filename="+fileName);
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len =0;
byte[] buffer = new byte[1024];
// 6. 获取OutPutStream
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutStream流写入到buffer缓冲区
// 8. 使用OutOutStream将缓冲区的数据输出到客户端!
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.6.3验证码功能
package com.mahui.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.如何让浏览器每个三秒自动刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();
//设置图片的背景颜色
g.setColor(Color.WHITE);
g.fillRect(0,0,150,20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.ITALIC,20));
g.drawString(mkNum(),0,20);
//告诉浏览器,这个请求用图片的格式打开
resp.setContentType("image/jpg");
//网站存在缓存,不让浏览器有缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
private String mkNum(){
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer sb = new StringBuffer();
for (int i = 0; i <7-num.length() ; i++) {
sb.append(0);
}
num=sb.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.6.4实现重定向
什么是重定向:
B收到客户端A的请求后,B会通知客户端A去访问另一个web资源C,这个过程叫做重定向
常见的场景:
- 用户登录
void sendRedirect(String var1) throws IOException;
重定向的测试:
package com.mahui.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
resp.setHeader("Location","/r/image");
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
*/
//实现重定向
resp.sendRedirect("/r/image");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
面试题:重定向和转发的区别 ?
相同点:
- 页面都会实现跳转
不同点:
- 请求转发时,url不会发生改变 307
- 重定向时,url地址栏会发生改变 302
8.6.5简单实现登录重定向
index.jsp
<html>
<body>
<h2>Hello World!</h2>
<%--${pageContext.request.contextPath}/login 当前项目下寻找--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
succes.jsp
<h1>success</h1>
servlet实现登录重定向的代码
package com.mahui.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 RequestDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向 一定要注意路径问题
resp.sendRedirect("/r/succes.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.7HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息都被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。
8.7.1获取参数,请求转发
java代码
package com.mahui.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class RequestDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println(username+":"+password+"--"+ Arrays.toString(hobbys));
//请求转发 这里的/代表的当前是web项目
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--${pageContext.request.contextPath} 当前的web应用--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名: <input type="text" name="username" ><br>
密码: <input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobbys" value="女孩"> 女孩
<input type="checkbox" name="hobbys" value="跳绳">跳绳
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="学习">学习
<input type="submit">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
web.xml
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.mahui.servlet.RequestDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
9.Cookie,Session
9.1会话
会话:当用户打开一个浏览器,点击了很多的超链接,访问了多个web资源,之后关闭浏览器,这个过程称为会话。
有状态会话:比如说一个人去过商场,当他下次再来的的话,我们知道这个人曾经来过,这个就称之为有状态绘画;
一个网站怎么证明你来过?
客户端 服务端
- 服务端给客户端一个信件。客户端下次访问服务端的时候带上这个信件;cookie
- 服务端会登记你来过,下次你来的时候我来匹配你;session
9.2保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在session中
常见应用场景:我们登录一个网站之后,下次来的时候就不用登录。第二次直接访问就登录上去了
9.3Cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//从请求中获得cookie
cookie.getName()//获得cookie的key
cookie.getValue()//获得cookie的value
Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");//创建一个cookie对象
resp.addCookie(cookie);//给客户端响应一个cookie
cookie.setMaxAge(60);//设置cookie的保存时间
cookie的练习
package com.mahui.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置中文编码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//获得输出
PrintWriter out = resp.getWriter();
//获得cookie 这里返回数组,说明cookie可能存在多个
Cookie[] cookies = req.getCookies();
//判断cookie是否存在
if(cookies!=null) {
//如果存在怎么办
out.write("你上一次访问的时间:");
//遍历cookies
for (int i = 0; i <cookies.length ; i++) {
Cookie cookie = cookies[i];
//找到需要找的cookie
//使用equals() 不能使用==
if(cookie.getName().equals("lastLoginTime")){
String s = cookie.getValue();
long l = Long.parseLong(s);
Date date = new Date(l);
String lastLoginTime = date.toLocaleString();
out.write(lastLoginTime);
}
}
}else {
out.write("这是你第一次访问本站");
}
//设置一个cookie
Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
//给客户端响应cookie
resp.addCookie(cookie);
cookie.setMaxAge(60);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
cookie:一般会保存在本地的用户目录下appdata;
一个网站cookie是否会有上限:
- 一个cookie只能保存一个信息。
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- cookie大小有限制4kb
- 300个cookie是浏览器上限
删除cookie
- 不设置有效期,关闭浏览器自动失效
- 设置cookie有效期时间为0
编码解码问题
URLEncoder.encode("猪猪侠","utf-8") //编码的问题
URLDecoder.decode(cookie.getValue(),"UTF-8")//解码的问题
9.4Session(重点)
1.什么是session
- 服务器会给每一个用户(浏览器)创建一个session对象
- 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
- 用户登录之后,整个网站都可以访问
2.Session和Cookie的区别:
- Cookie是把用户的数据写给用户浏览器,浏览器进行保存(可以保存多个)
- Session把用户的数据写到用户独占的session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- session对象是由服务器创建的
3.使用的场景
- 保存一个登录用户的信息
- 购物车信息
- 整个网站中经常会使用的数据,我们将它保存在在session中
4.session的使用
//获得session
HttpSession session = req.getSession();
//geisession中存放东西
session.setAttribute("name","张三");
//去除session中存放的信息
session.removeAttribute("name");
//手动注销Session
session.invalidate();
-
使用session进行信息保存
package com.mahui.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; public class SessionDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置字符集编码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); // PrintWriter out = resp.getWriter(); //获得session HttpSession session = req.getSession(); //geisession中存放东西 session.setAttribute("name","张三"); //获得sessionid String sessionId = session.getId(); //判断session是不是新创建的 if(session.isNew()){ out.write("session是新创建的,ID为"+sessionId); }else { out.write("session不是新创建的,ID为"+sessionId); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
-
获得session内存储的值
package com.mahui.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; public class SessionDemo02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); HttpSession session = req.getSession(); String name = (String) session.getAttribute("name"); //System.out.println(name); PrintWriter out = resp.getWriter(); out.write(name); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
5.会话的自动过期在web.xml配置
<!--设置session的默认失效时间-->
<session-config>
<!--设置session的默认失效时间,以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
10. JSP
10.1什么是JSP?
Java Server Pages:Java服务器端页面,也和servlet一样,用于动态的Web技术!
特点:
- 写JSP就像写HTML
- 区别
- HTML只给用户提供静态的数据
- JSP页面中可以起嵌入JAVA代码,为用户提供动态数据
10.2JSP原理
思考:JSP是如何执行的?
-
代码层面没有任何的问题
-
服务器内部工作
tomact中有一个work目录;
IDEA中使用Tomcat的会在IDEA的tomcat中生成一个work目录
我自己的目录:
C:\Users\Administrator\.IntelliJIdea2018.2\system\tomcat\Unnamed_javaWeb04maven\work\Catalina\localhost\web04\org\apache\jsp
发现里边的页面转换为java文件
打开java文件:jsp的本质是一个servlet
浏览器在向服务器发送请求时,不管访问什么资源,其实都是在访问Servlet
JSP最终会被转换为一个Java类
JSP本质上就是一个Servlet
//初始化
public void _jspInit() {
}
//销毁
protected void _jspDestroy() {
}
//JSPservice
public abstract void _jspService(HttpServletRequest var1, HttpServletResponse var2) throws ServletException, IOException;
1.判断请求
2.内置一些对象
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; //oout
final java.lang.Object page = this; //page 当前
HttpServletRequest request //请求
HttpServletResponse response //响应
3.输出页面前增加的代码
response.setContentType("text/html;charset=UTF-8");//设响应置页面的类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
4.以上的这些对象我们可以在JSP页面中直接使用
JSP执行流程:
在JSP页面中
是java代码的就会原封不动的输出
如果是HTMl代码,就会被转换为:
out.write("\n");
out.write("\n");
out.write("<html>\n");
out.write(" <head>\n");
out.write(" <title>$Title$</title>\n");
out.write(" </head>\n");
out.write(" <body>\n");
out.write("\n");
out.write(" ");
这样的格式,输出到前端!
10.3 JSP基础语法
<%= jsp表达式%>
<% jsp 脚本片段%>
<%! jsp声明 %>
<%--jsp注释--%>
注意: jsp的注释不会再客户端显示,HTML的注释会显示在客户端
学习jsp需要导入的依赖:
servlet-api
jsp-api
jstl-api
standard
10.3.1JSP表达式
<%--jsp 表达式
作用:用来将程序输出,输出到客户端
--%>
格式<%= 变量或者表达式%>
<%= new java.util.Date()%>
10.3.2JSP脚本片段
<%
int sum=0;
for (int i = 0; i <100 ; i++) {
sum+=i;
}
out.println("<h1>"+sum+"</h1>");
%>
格式:<% %>
10.3.3JSP声明
<%!
static {
System.out.println("进入了static");
}
public void in(){
}
%>
格式:<%! %>
通过jsp编译之后的java文件进行分析
jsp表达式和jsp的脚本片段都编译在_jspService()方法中
jsp声明是全局的存在于index_jsp类中
10.4JSP指令
<%@page args... %>
<%@ include file=""%>
10.4.1 500页面错误指定自己的页面显示
<%@page errorPage="error/500.jsp" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page errorPage="error/500.jsp" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
int i= 1/0;
%>
</body>
</html>
10.4.1.1404,500配置
当出现404页面跟500页面的时候如何在web里边配置使其显示自己的页面
<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>
10.4.2 网页的拼接
<%@include file="common/header.jsp"%>
<h1>这是主体</h1>
<%@ include file="common/footer.jsp"%>
jsp:include 拼接页面,本质还是三个
10.5 9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application 【SerlvetContext】 存东西
- config 【SerlvetConfig】
- out
- page ,不用了解
- exception
<%
pageContext.setAttribute("name01","name1");//保存的数据只在一个页面中有效
request.setAttribute("name02","name2");//保存的数据只在一次请求中有效,请求转发时携带数据
session.setAttribute("name03","name3");//保存的数据 只在一次会话中有效。从打开浏览器到关闭浏览器
application.setAttribute("name04","name4");//保存的数据只在一个服务器上有效,从打开服务器到关闭服务器
%>
request: 客户端向服务器发送请求,产生数据,用户看完后就没用了,比如:新闻,用户看完没用的
seesion:客户端向服务器发送请求,产生数据 ,用户用完之后还有用,比如:购物车
appliacation:客户端向服务器发送请求,产生数据,一个用户用完,其他用户还可能使用,比如:聊天数据
测试代码
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/12/4 0004
Time: 14:55
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
pageContext.setAttribute("name01","name1");//保存的数据只在一个页面中有效
request.setAttribute("name02","name2");//保存的数据只在一次请求中有效,请求转发时携带数据
session.setAttribute("name03","name3");//保存的数据 只在一次会话中有效。从打开浏览器到关闭浏览器
application.setAttribute("name04","name4");//保存的数据只在一个服务器上有效,从打开服务器到关闭服务器
%>
<%
String name1= (String) pageContext.findAttribute("name01");
String name2= (String) pageContext.findAttribute("name02");
String name3= (String) pageContext.findAttribute("name03");
String name4= (String) pageContext.findAttribute("name04");
String name5= (String) pageContext.findAttribute("name05");
%>
<h1><%= name1%></h1>
<h1><%= name2%></h1>
<h1><%= name3%></h1>
<h1><%= name4%></h1>
<h1><%= name5%></h1>
</body>
</html>
可以设置作用域
pageContext:
pageContextImpl
pageContext.setAttribute("name","name",PageContext.PAGE_SCOPE); //page
pageContext.setAttribute("name","name",PageContext.REQUEST_SCOPE);//request
pageContext.setAttribute("name","name",PageContext.SESSION_SCOPE);//session
pageContext.setAttribute("name","name",PageContext.APPLICATION_SCOPE);//application
10.9 JSP标签 JSTL表达式 EL表达式
jsp标签和jstl表达式需要导入的依赖
<!--jstl表达式的依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
10.9.1EL表达式 ${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
10.9.2 JSP标签
- 进行jsp页面的拼接:
<jsp:include page="common/header.jsp" ></jsp:include>
<h1>这是主体</h1>
<jsp:include page="common/footer.jsp"></jsp:include>
</body>
- 请求转发
<jsp:forward page="/jsptag02.jsp">
<jsp:param name="username" value="zhangsan"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
在请求转发的页面拿到param
用户名:<%= request.getParameter("username")%> <br>
年龄:<%= request.getParameter("age")%>
10.9.3 JSTL表达式
JSTL标签库的使用是为了弥补HTML标签的不足,它自定义许多标签,可以供我们使用,标签的功能和java代码一样
菜鸟教程学习地址:https://www.runoob.com/jsp/jsp-jstl.html
JSTL标签的分类:
- 格式化标签
- SQL标签
- XML标签
- 核心标签
JSTL标签库的使用步骤
- c:if标签
<%--一个提交的表单
提交的地址:cif.jsp 提交的方式 get
name = username
value 就是提交的参数
--%>
<form action="cif.jsp" method="get">
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--if判断提交的值是否等于admin ,返回的值var 定义为isadmin 返回是true或者flase--%>
<c:if test="${param.username=='admin'}" var="isadmin">
<%--如果等于admin就输出--%>
<c:out value="登录成功"/>
</c:if>
<c:out value="${isadmin}"/>
2.c:choose
<%--定义一个变量score 值为60--%>
<c:set var="score" value="60" />
<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>
3.c:foreach
<%
ArrayList people =new ArrayList();
// 这里的index必须从0开始
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
people.add(4,"宋七");
// 将list通过请求拿到
request.setAttribute("list",people);
%>
<%--foreach 遍历--%>
<%--
var :每一次遍历出来的变量
items: 要遍历的对象
begin:哪里开始
end: 到哪里
step: 步长
--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/>
</c:forEach>
11. JavaBean
实体类:pojo
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有
- 必须要有对应的get/set方法
一般用来和数据库的字段进行映射 :ORM;
ORM:对象关系映射
- 表—>类
- 字段—>属性
- 行记录—>对象
例如:
people表
id | name | age | address |
---|---|---|---|
1 | name1 | 45 | 陕西 |
2 | name2 | 63 | 山西 |
3 | name3 | 21 | 北京 |
4 | name4 | 65 | 武汉 |
对应的具体people类:
class People{
private int id;
private String name;
private int id;
private String address;
}
class A{
new People();
}
jsp中通过javabean创建对象
<%
// People people= new People();
// people.setId();
// people.setName();
// people.setAge();
// people.setAddress();
%>
<jsp:useBean id="people" class="com.mahui.pojo.People">
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="张三"/>
<jsp:setProperty name="people" property="age" value="1"/>
<jsp:setProperty name="people" property="address" value="陕西"/>
</jsp:useBean>
<%
//people.getId();
//people.getName();
//people.getAge();
//people.getAddress();
%>
id:<jsp:getProperty name="people" property="id"/>
name:<jsp:getProperty name="people" property="name"/>
age:<jsp:getProperty name="people" property="age"/>
address:<jsp:getProperty name="people" property="address"/>
pojo:people类
package com.mahui.pojo;
import java.lang.String;
public class People {
private int id;
private String name;
private int age;
private String address;
public People() {
}
public People(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
12.MVC三层架构
什么是MVC:Model (模型) view (视图) Controller(控制层)
12.1早期架构
用户可以直接访问控制层,控制层直接从数据库中拿到数据
servlet ---->jdbc ---->数据库
弊端:会造成代码的臃肿,不利于维护
servlet中 :接收请求,处理请求,响应,试图跳转,处理JDBC,处理业务代码,处理逻辑代码
12.2MVC三层架构
Model:
- 业务处理:业务逻辑(Service)
- 数据的持久:JDBC(dao)
View:
- 展示数据
- 提供链接发起servlet请求(a form img)
Controller(Servlet)
- 接收用户的请求(re:请求参数,Session信息…)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录--->接收用户的登录---->处理用户的请求(获取用户登录的参数,username,password) ---->交给业务层处理登陆业务(判断用户名密码是否正确)--->Dao曾查询用户名和密码是否正确--->数据库
13Filter
filter:过滤器,用来过滤网站的数据
- 处理中文乱码
- 登录验证
Filter开发步骤:
1.导包:javax.servlet下的包
2.编写过滤器
package com.mahui.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
//初始化:web服务器一启动就进行初始化 ,随时等待过滤对象的 出现
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter进行了初始化");
}
//chain:链
//必须让过滤器同行
// 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("过滤器执行前");
//让请求继续走,如果不写这行代码,请求被拦截就不会继续往下走
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("过滤器执行后");
}
//销毁:web服务器停止时,过滤器进行销毁
public void destroy() {
System.out.println("CharacterEncodingFilter进行了销毁");
}
}
3.在web.xml里注册过滤器
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.mahui.filter.CharacterEncodingFilter</filter-class>
</filter>
<!--/servlet下的所有请求都会被过滤-->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
14.Listener
编写一个监听器
1.实现监听器的接口
package com.mahui.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数 统计session即可
public class OnlineCountListener implements HttpSessionListener {
//创建一个session 多个一个用户
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
//输出sessionid
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(onlineCount == null){
onlineCount =new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount=new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁一个session 用户减少一次
/*
* 销毁session的两种方式
* 1.手动销毁: se.getSession().invalidate();
* 2.自动销毁:在web页面配置,设置销毁的时间
* <session-config>
<session-timeout>1</session-timeout>
</session-config>
* */
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);
}
}
2.web.xml注册监听器
<listener>
<listener-class>com.mahui.listener.OnlineCountListener</listener-class>
</listener>
15.过滤器及监听器常用的案例
1.权限的判断
- 用户登录后向session中放入用户数据
- 进入主页的时候判断用户是否进行了登录,在过滤器中实现
- 过滤器代码实现
package com.mahui.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//将ServletRequest转为HttpServletRequest
HttpServletRequest req =(HttpServletRequest) servletRequest;
HttpServletResponse resp =(HttpServletResponse) servletResponse;
//获得session
Object username = req.getSession().getAttribute("USER_NAME");
//进行判断
if(username == null){
resp.sendRedirect("/error.jsp");
}
//让程序继续执行
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
web.xml中配置
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.mahui.servlet.loginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.mahui.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
登录处理的servlet
package com.mahui.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 loginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
if(username.equals("admin")){
req.getSession().setAttribute("USER_NAME",req.getSession().getId());
//登录成功!
resp.sendRedirect("/sys/success.jsp");
}else {
//登录失败
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/servlet/login" method="post">
<input type="text" name="username">
<input type="submit" name="提交">
</form>
</body>
</html>