admin管理员组文章数量:1646247
JSP+Servlet+JDBC
1.Web相关概念
1.1软件架构
- B/S:浏览器端/服务器端
- C/S:客服端到服务器端
1.2资源分类
-
静态资源:所有用户访问结果都一样,成为静态资源,静态资源可以直接被浏览器解析
- 如HTML,CSS
-
动态资源:每个用户访问相同的资源,得到结果可能不同,称为动态资源。动态资源被访问后,需要先转换为静态资源,再返回给浏览器。
- 如JSP+Servlet,php
1.3网络通信三要素
IP:电子设备在网络中唯一标识
端口:应用程序在计算机中唯一标识。0-65536
传输协议:规定了数据的传输规则。
1.TCP:可靠,三次握手,速度慢,数据大小无限制
2.UDP:不可靠,不建立连接,传输速度快,数据大小有限制
1.4服务器
-
服务器:安装了服务器软件的计算机
-
服务器软件:接受用户请求,处理请求,做出响应的软件
-
web服务器软件:接受用户请求,处理请求,做出响应的软件
-
它里面可以部署web项目,让用户通过浏览器来访问这些项目
-
动态资源必须依赖web服务器才能运行,所以也被称为web容器
-
-
常见的Java相关的web服务器软件
- Tomcat: Apache基金组织,中小型的JavaEE服务器,仅支持少量JavaEE规范,开源免费,性能优异,支持集群,所以深受广大企业喜爱。
- webLogic:oracle公司,大型的JavaEE服务器,支持所有JavaEE规范,收费
- webSphere:IBM公司,大型的JavaEE服务器,支持所有JavaEE规范,收费
- JBOSS:JBoss公司,大型的JavaEE服务器,支持所有JavaEE规范,收费
2.Tomcat
2.1下载
2.2安装
解压即可使用
建议:安装目录不要有中文和空格
2.3目录结构
2.4卸载
删除文件夹即可
2.5启动
bin/startup.bat
启动报错
- 解决方案:logs----catalina.当天日期.log—在日志找错误信息----百度
启动窗口闪退
- 解决方案:JAVA_HOME配置有问题,正确配置后,就可以修复此问题
重复启动,端口号占用(日志)
- 解决方案1:干掉端口号:cmd—netstat (-ano)–看最右PID后在任务管理器详细信息找到结束任务
- 解决方案2:修改Tomcat端口号,(config—server.xml—修改8080)
2.6关闭
-
正常关闭
- bin/shutdown.bat
- 启动窗口:ctrl+c
-
强制关闭
- 右上角点
x
- 右上角点
2.7项目部署
方式1:直接将项目复制到webapps下
- /MyWeb项目访问路径,其实他是一个虚拟路径,没有配置前,默认是实际路径
方式2:将项目打包成war包复制到webapps下
- 服务器会为我们自动的部署项目,删除项目只需删除war包,对应的项目也会自动被删除
方式3:通过配置server.xml
1.在配置文件中找到Host标签
2.在Host标签中加入配置
<Context docBase="项目路径" path="虚拟路径" />
- Context:自闭和标签
- docBase:项目存放路径
- path:访问的虚拟路径
缺点:server.xml是针对服务器的配置文件,一般我们不会修改这个文件,因为稍有不慎,就会导致服务器崩溃
方式4:在conf/Catalina/localhost/文件夹中创建 虚拟路径.xml
- 在该xml文件中添加标签
<Context docBase="D:\MyLove" path="/baidu" />
该方式的好处:1.不用修改配置文件,2支持热部署
3.Servlet
3.1概述
运行在服务端的java小程序
- Servlet是一个接口,定义了Java类可以被Tomcat识别的规则
- 针对Servlet的开发就是实现Servlet接口,重写里面的方法即可
3.2快速入门
步骤:
1.创建JavaEE项目
2.定义一个类,实现Servlet接口
3.实现接口中的抽象方法
4.配置Servlet
创建Servlet无法实现接口解决方式:
打开web.xml配置如下代码
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>org.wdit.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
或者导入tomcat下的servlet-api.jar
执行原理:
1.服务器接收到浏览器的请求后,会解析URL路径,获取访问Servlet的资源路径(/demo)
2.查找web.xml
文件中是否有对应的<url-pattern>
3.如果有,就会找到对应的<Servlet-class>
,拿到对应的Servlet的全限定类名
4.tomcat将对应的字节码文件加载到内存中,并创建该类对象
5.调用service()方法
3.3 Servlet方法和生命周期
1.生命周期:
-
被创建:执行init方法 ,只执行一次
- init()方法加载时间可以被改变:通过web.xml配置
-
提供服务:执行service()方法,执行多次
-
被销毁:服务器正常关闭,执行destroy,只执行一次
注意事项:Servlet是单例模式:
多个用户访问可能存在线程安全问题,尽量不要使用Servlet中使用成员变量(在堆内存中),即使定义了成员变量,也不要有修改值的操作。
3.4注解配置
步骤:
1.创建JavaEE项目,选择3.0之后的版本,可以不创建web.xml
2.定义一个类,实现Servlet接口
3.重写方法
4.在类上使用注解进行配置
注意
1.Web-inf下的资源被浏览器访问不到
2.工作空间的项目和tomcat部署的web项目(CATALINA_BASE\work
)并不是一个项目
3.5Servlet继承体系结构
Servlet接口
|实现
GenericServlet 抽象类
|继承
HttpServlet抽象类
- GenericServlet 抽象类:它将Servlet接口中的其他方法都做了实现,只留下了Service()方法作为抽象方法
- HttpServlet抽象类:该抽象类是对Http协议的一种封装,可以简化操作
3.6HttpServlet
步骤:
1.定义类,继承HttpServlet
2.重写doPost()/doGet()
3.7 urlPatterns()属性
1.一个Servlet可以配置多个访问路径
2.路径定义规则:
-
路径匹配:/xxx
-
目录结构匹配:/xxx/xxx
-
扩展名匹配:*.xxx
-
package org.wdit.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /*HttpServlet*/ //@WebServlet("/demo2") @WebServlet(urlPatterns = {"/a","/aa","/aaa"}) public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("deGet......."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost.........."); } }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="demo2" method="post"> <input type="text" name="usename"> <input type="password" name="password"> <input type="submit" value="登录" > </form> </body> </html>
4.Http协议
4.1概念
Http:Hyper Text Transfer Protocol-超文本传输协议
4.2特点
1.基于TCP/IP的高级协议:安全的
2.默认端口号:80
3.基于请求和响应模型:一次请求对应一次响应
图示:
4.3请求消息-数据格式
GET / HTTP/1.1
Host: www.baidu
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BAIDUID=7ED3E8EA26D338BCDA80C3EC13DC3C83:FG=1; BIDUPSID=7ED3E8EA26D338BCF730592B5E7B5F74; PSTM=1614497992; BD_HOME=1; H_PS_PSSID=33514_33355_33257_33344_33595_33570_26350_33568; BD_UPN=13314752; BA_HECTOR=0g8k248184040080q91g3mie40r
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
4.4请求行
格式:请求方式 /请求的URL/请求的协议/版本号
请求方式:
-
GET
-
请求参数在请求行中,URL后
-
请求的URL长度是有限制的
-
不安全的
-
POST
- 请求参数在请求体中
- 请求的URL长度无限制
- 相对安全
4.5请求头
请求头内容就是浏览器告诉服务器它自身的一些信息。
-
常见的请求头
- Host:被请求的主机
- User-Agent:浏览器告诉服务器,当前浏览器的版本信息
- Accept:浏览器告诉服务器自己支持的格式
- Referer:告诉服务器,当前请求从哪里来
4.6请求空行
4.7请求体
格式:参数:对应的值
POST/ HTTP/1.1
Host: www.baidu
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BAIDUID=7ED3E8EA26D338BCDA80C3EC13DC3C83:FG=1; BIDUPSID=7ED3E8EA26D338BCF730592B5E7B5F74; PSTM=1614497992; BD_HOME=1; H_PS_PSSID=33514_33355_33257_33344_33595_33570_26350_33568; BD_UPN=13314752; BA_HECTOR=0g8k248184040080q91g3mie40r
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
//请求空行
usename=aaa & password=aaa
5.Request对象
5.1 request和 response对象的原理
通过原理图,我们得出:
1.request和response对象是由服务器创建,我们直接使用即可
2.request对象用来获取请求消息,response对象设置响应消息
ServletRequest----接口
|(被继承)
HttpServletRequest----接口
|(被实现)
org.apache.catalina.connector.RequestFacade-----------由tomcat在该类中做的具体实现
5.3获取请求消息数据
5.3.1获取请求行数据
我们根据请求行的格式来分析需要的方法
Get /demo2/demo2 HTTP/1.1
-
获取请求方法:GET
- String getMethod()
-
获取虚拟目录:/demo2
- String getContextPath()
-
获取资源路径:/a/(/aa)/(/demo2)
- String getServletPath()
-
获取get方式请求参数:?usename=aaa&password=aaa
- String getQueryString()
-
获取请求URI:/demo2/demo2
- String getRequestURI():
/demo2/demo2
- String getRequestURL():
http://localhost:8080/demo2/demo2
- String getRequestURI():
-
获取协议及版本号:HTTP/1.1
- String getProtocol()
获取客户机的IP地址
- String getRemoteAddr()
package org.wdit.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /**/ @WebServlet("/demo3") public class ServletDemo3 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post........"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取请求方式 String method = req.getMethod(); System.out.println(method); //2.获取虚拟目录 String contextPath = req.getContextPath(); System.out.println(contextPath); //3.获取Servlet路径 String servletPath = req.getServletPath(); System.out.println(servletPath); //4.获取get方式请求参数 String queryString = req.getQueryString(); System.out.println(queryString); //5.获取请求URI String requestURI = req.getRequestURI(); StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURI); System.out.println(requestURL); //6.获取协议及版本号 String protocol = req.getProtocol(); System.out.println(protocol); //7.获取客户机的IP String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); } }
5.3.2获取请求头
- String getHeader(String name):通过请求头的名称获取请求头的值
- **Enumeration getHeaderNames()😗*获取所有请求头名称
- Enumeration相当于迭代器
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**/
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//根据头对应的名称拿对应的值
String value = req.getHeader(name);
System.out.println(name+"----"+value);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
防盗链案例演示
package org.wdit.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/*防盗链演示*/
@WebServlet("/demo6")
public class ServletDemo6 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取referer
String referer = req.getHeader("referer");
System.out.println(referer);
if(referer.contains("http://localhost:8080/")){
System.out.println("开始播放。。。。。。");
}else{
System.out.println("滚");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post..........");
}
}
5.3.3获取请求体
- 请求体:只有POST方式有请求体
- 步骤:
- 获取流对象
- 从流中获取数据
package org.wdit.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
/*获取请求体数据*/
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*//1.获取流
BufferedReader reader = req.getReader();
//2.读数据
String line=null;
while((line=reader.readLine())!=null){
System.out.println(line);
}*/
//获取流
ServletInputStream inputStream = req.getInputStream();
byte[]bytes=new byte[1024];
int len=0;
while((len=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
len=inputStream.read(bytes);
}
5.3.4其他方法
这些方法是在前面基础方法上衍生出来的一些通用方法,更方便使用
1.获取请求参数对象(GET/POST)都能用
-
**String getParameter(String name)**根据参数名称获取参数值
-
**String[] getParameterValues(String name)**根据参数名获取参数值的数组
-
**Enumeration getParameterNames()😗*获取所有请求的参数名称
-
Map<String,String[]> getParameterMap():获取所有参数的Map集合
-
解决中文乱码问题
- request.setCharacterEncoding(“utf-8”)
package org.wdit.servlet;
import jdk.dynalink.linker.GuardingTypeConverterFactory;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@WebServlet("/demo8")
public class ServletDemo8 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//根据参数名获取参数值
String usename = req.getParameter("usename");
String password = req.getParameter("password");
System.out.println(usename+"----"+password);
//获取复选框的参数值
String[] hobbies = req.getParameterValues("hobby");
for(String hobby:hobbies){
System.out.println(hobby);
}
//获取请求中所有的参数名
Enumeration<String> parameterNames = req.getParameterNames();
while(parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
String value = req.getParameter(name);
System.out.println(name+": "+value);
}
//返回所有参数的Map集合
Map<String, String[]> parameterMap1 = req.getParameterMap();
//遍历Map集合
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> keys = parameterMap.keySet();
Iterator<String> iterator = keys.iterator();
while(iterator.hasNext()){
String s = (String)iterator.next();
String[] values = parameterMap.get(s);
for(String value:values){
System.out.println(s+"----"+value);
}
}
}}
2.请求转发
-
概述:一种在服务器内部资源跳转的方式
-
步骤:
1.通过request对象获取请求转发器对象
- RequestDispatcher getRequestDispatcher(String path)
2.使用转发器对象进行转发
- forward(ServletRequest request,ServletResponse response)
package org.wdit.servlet; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import java.util.Set; @WebServlet("/demo9") public class ServletDemo9 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); System.out.println("demo9被访问了"); //转发 req.getRequestDispatcher("/demo10").forward(req,resp); }}
-
特点:
1.浏览器地址栏路径不发生变化
2.只能转发当前服务器内部资源
3.转发它是一次请求:无论内部转发多少次,调用几个Servlet,它都是一次请求
3.数据共享
-
概述:多个Servlet间协作 数据的共享,在学习共享之前,我们需要学习:域对象
-
域对象:一个有作用范围的对象,在作用范围之内可以共享数据
-
Request域:代表一次请求的范围。它的作用范围刚好就是请求转发的范围,所以request域对象一般用于多个资源共享数据。一次请求多个资源
1. **void setAttribute(String name,Object obj)😗*存储数据
2. **Object getAttribute(String name)**:获取数据 3. **void remove Attribute(String name)**:删除数据
设置请求参数
package org.wdit.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@WebServlet("/demo9")
public class ServletDemo9 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
System.out.println("demo9被访问了");
//转发
req.getRequestDispatcher("/demo10").forward(req,resp);
req.setAttribute("info","我真厉害");
}}
收到参数
package org.wdit.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo10")
public class ServletDemo10 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
System.out.println("demo10被访问了");
Object info = req.getAttribute("info");
System.out.println(info);
}}
4.ServletContext对象
- ServletContext getServletContext()
- 后面细讲 很重要
5.4用户登录
需求:
1.编写login.html登陆页面
2.连接数据库,判断页面传来的用户信息是否在数据库中存在
3.根据查询信息
- 存在:登陆成功----转发到SuccessServlet并在页面输出欢迎+用户名+登录
- 不存在:登陆失败—转发到ErroServlet并在页面输出:用户名或密码错误
分析:
1.新建Module
- 添加web依赖
- 配置tomcat-将该项目部署到tomcat-中文乱码,虚拟路径
2.导包:mysql驱动包,Druid连接,JDBCTemplate
3.添加配置文件:druid.properties
4.创建包结构,添加工具类:JDBCUtils(org.wdit.utils)
5.5BeanUtils使用要求
1.类必须是public
2.类必须提供无参构造
3.成员变量必须被private修饰
4.提供公共的get/set方法
6.Http响应消息
1.请求消息:客户端发送给服务端数据
- 请求行
- 请求头
- 请求空行
- 请求体:
- Post:有请求体
- Get:以参数的方式,在请求行中
2.响应消息:服务器回应给客户端消息
- 响应行
- 响应头
- 响应空行
- 响应体
6.1响应行
1.组成
协议/版本 响应状态码 响应码描述
2.状态码
- 分类:
- 1xx- 服务端接收客户端信息,但没有接收完成,等待一段时间后,发1xx状态码,询问客户端是否继续发送消息
- 2xx-成功 代表:200
- 3xx-重定向,资源跳转的方式,代表码:302-重定向 304-访问缓存
- 4xx:客户端错误,比如访问路径有问题,没有对应资源:404
- 5xx:服务端错误,比如服务器代码出现异常:500
6.2响应头
1.组成
头名称:值
2.常见响应头
- content-type :服务器告诉客户端本次响应体数据格式即编码 格式
- content-dispotion:服务器告诉客户端以什么方式打开响应体数据,如果没有设置,则使用默认值
- in-line:默认值,在当前页面打开
- attachment;filename=xxx:以附件按形式打开响应体。及文件下载filename是文件下载的默认名字
6.3验证码
**本质:**就是一张图片
**目的:**提高安全性,防止恶意注册,恶意登录
**方式:**随机产生
7.Response对象
7.1概述
Response对象是用来设置响应消息的
7.2主要方法
1.设置响应行
- 设置响应状态码:setStatus(int SC)–SC:状态码
2.设置响应头
- setHeader(string name,String value)
package org.wdit.response;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*重定向*/
@WebServlet("/resp1")
public class responseDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("responseDemo被访问");
// //设置状态码
// resp.setStatus(302);
// //设置响应头
// resp.setHeader("location","/demo2/resp2");
String contextPath=req.getContextPath();
resp.sendRedirect(contextPath+"/resp2");
//简化书写
// resp.sendRedirect("/demo2/resp2");
}
}
3.设置响应体
-
步骤:
-
1.获取输出流
- 字节输出流:ServletOutputStream getOutputStream()
- 字符输出流:printWriter getWriter()
-
2.使用输出流将数据输出客户端浏览器
public class responseDemo3 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置头信息 //resp.setHeader("content-type","text/html;charset=utf-8"); resp.setContentType("text/html;charset=utf-8"); resp.getWriter().write("哈哈"); /* //获取输出流 PrintWriter printWriter= resp.getWriter(); printWriter.write("<h1>Hello response</h1>"); printWriter.write("你好,response");//乱码*/ /* * 分析:中文乱码 * QQ浏览器:默认GBK * 输出流通过Tomcat获取:编码集理论上应该是ISO-8859-1 * * */ //解决中文乱码 /*//1.获取流之前设置编码集 resp.setCharacterEncoding("GBK"); */ } }
-
输出字节流
public class responseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码
resp.setContentType("text/html;charset=utf-8");
//获取流
resp.getOutputStream().write("你好".getBytes());
}
}
7.3重定向
图解:
步骤:
1.设置状态码:302
2.设置响应头:Location
面试题: 转发forward 和 重定向redirect 区别:
-
转发:
1.一次操作,一次请求
2.服务器内部资源间操作
3.地址栏路径url没变
4.只能访问当前服务器资源
5.可以使用request对象共享数据
-
重定向:
1.一次操作,多次请求
2.客户端和服务器间的操作
3.地址栏路径url改变
4.可以访问外部服务器资源
5.不可以使用request对象共享数据,因为重定向是两次请求
-
路径书写:
-
相对路径:找到当前资源 和 目标资源之间的相对位置关系
./
开头../
表示上一级目录
-
绝对路径
-
以
/
开头:因为当前项目中localhost:8080/虚拟目录
都是统一格式,所以我们可以省略为/
-
判断标准“
1.浏览器使用,需要加虚拟目录
2.服务器使用不需要加虚拟目录
-
-
8.ServletContext对象
8.1概述
ServletContext对象代表整个Web应用
8.2获取对象
1.通过Request对象获取
- request.getServletContext()
2.通过HttpServlet获取
- this.getServletContext()
8.3功能
1.获取MIME类型
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式:大数据类型/小数据类型 比如:text/ html
- 获取:String getMimeType(String file):通过文件名(包括扩展名)获取MIME的值
- 扩展名对应的MIME值可以通过tomcat安装路径—conf—web.xml查看
2.域对象:共享数据
- void seSetAttribute(String name ,Object obj):存储数据
- **Object getAttribute(String name)😗*通过参数名获取参数值
- **void removeAttribute(String name)😗*通过移除参数名删除数据
3.作用域
- 最大范围 :所有用户的所有连接
两次请求案例
package org.wdit.ServletContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/context3")
public class ServletContextDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = req.getServletContext();
servletContext.setAttribute("info","AEd2 ");
}
}
package org.wdit.ServletContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/context4")
public class ServletContextDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = req.getServletContext();
String info = (String) servletContext.getAttribute("info");
System.out.println(info);
}
}
8.4文件下载
需求:
1.在html文件中写一个超链接
2.点击超链接弹出下载提示框
如果超链接 href指向图片路径,因为浏览器的解析器可以解析图片,所以会直接显示出来,如果指向的是视频,因为浏览器无法解析,就会默认弹出下载框
3.下载文件
分析:
需要设置响应头设置资源打开方式,否则图片无法通过超链接进行下载
- content-disposition:attachment;filename=xxx
步骤:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/demo2/demo7" method="post">
请输入用户名: <input type="text" name="usename"><br>
请输入密码: <input type="password" name="password"><br>
<input type="submit" value="登录" >
</form>
<a href="/demo2/image/hx.jpg ">诗和远方</a>
<a href="/demo2/video/h.mp4 ">视频</a>
</body>
</html>
package org.wdit.ServletContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
/*
* 文件下载演示案例*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取文件名
String fileName=req.getParameter("fileName");
//获取文件真实路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/image/" + fileName);
//设置响应头
//设置MIME值
String mimeType = servletContext.getMimeType(fileName);
resp.setHeader("content-type",mimeType);
//设置打开方式
resp.setHeader("content-disposition","attachment;filename="+fileName);
//获取输入输出流
FileInputStream fis=new FileInputStream(realPath);
ServletOutputStream outputStream = resp.getOutputStream();
byte[]bytes=new byte[1024];
int len=0;
while((len=fis.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
//释放资源
fis.close();
}
}
9.会话技术
概述:
一次会话中包含多次请求和响应,并且在会话范围内可以共享数据
功能:
共享数据
分类:
1.客户端会话技术:Cookie
2.服务器端会话技术:Session
9.1Cookie
概述:
客户端会话技术,将数据保存在客户端
步骤:
1.创建Cookie对象
- new Cookie(String name,String value);
2.发送Cookie对象
- response.addCookie(String cookieName )
3.获取Cookie对象
- Cookie[] request.getCookies()
注意事项:
1.一次可以发送多个Cookie:创建多个Cookie对象,多次调用addCookie()
2.Cookie在浏览器中保存多长时间
- 默认情况下:浏览器关闭,Cookie数据被销毁
- 持久化存储:
- setMaxAge(int second):
- second:正数,将Cookie数据写入到磁盘文件中,持久化存储,second具体数值,表示文件存活的时长。以秒为单位
- 负数,默认值
- 0,删除Cookie信息,因为服务器无法直接操作用户电脑。
3.Tomcat 8之前,不能直接存储数据,8版本以后可以直接存储中文,但是特殊字符依然不能存储,需要使用URL编码和解码 来存储和获取数据
4.Cookie的获取范围:
1.相同服务器多个web项目
-
默认情况:一个Tomcat服务器中的多个Web项目是不共享Cookie数据的
-
我们可以通过方法设置:setPath("/"),这样Cookie就可以共享了
2.不同服务器
-
通过setDomain()方法设置相同的一级域名,这些不同服务器之间的Cookie就可以共享了
-
tieba.baidu:baidu就是一级域名
特点:
1.存储少量,内容不敏感的数据
2.大小有限制:单个Cookie大小-4kb,同一个域名下的总Cookie数不超过20个
用途:
在不登陆的情况下,完成服务器对客户端的识别
练习:
**需求:**访问网站时给出上一次登陆的信息:如果第一次登陆则显示首次登陆,如果不是第一次则显示上一次登录的时间。
分析:
1.采用Cookie来完成
-
用它来存储登录信息:setMaxAge (int second)
2.在服务器端Servlet中判断请求消息的消息头中是否有lastTime这个cookie
-
有:不是第一次访问
- 取出cookie的值,响应数据
- 更新lastTime这个Cookie
-
没有:第一次访问
- 响应:欢迎您,您是第一次登录
- 添加cookie:lastTime=当前时间戳
package org.wdit.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* 练习:显示上一次登录时间*/
//注解方式配置Servlet
@WebServlet("/cookie3" )
public class CookieDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置相应编码集
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取所有Cookie
Cookie[] cookies = req.getCookies();
boolean flag=false;//标记是否有lastTime
///3.遍历数组
if(cookies!=null&&cookies.length>0){
for(Cookie cookie:cookies){
//获取cookie名称
String name = cookie.getName();
//判断
if("lastTime".equals(name)){
//存在,不是第一次访问
//获取值
String value = cookie.getValue();
//URL解码
value = URLDecoder.decode(value, "utf-8");
//响应
resp.getWriter().write("<h1>您上一次访问的时间是:"+value+"</h1>");
//更新lastTime
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String newDate = sdf.format(date);
//进行URL编码
newDate = URLEncoder.encode(newDate, "utf-8");
cookie.setValue(newDate);
//设置cookie存活时长
//发送cookie
resp.addCookie(cookie);
flag=true;
}
}
}
//第一次访问的情况
if(cookies==null||cookies.length==0||flag==false){
//获取时间
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String newDate = sdf.format(date);
//进行URL编码
newDate = URLEncoder.encode(newDate, "utf-8");
System.out.println("编码后:"+newDate);
//创建Cookie对象
Cookie cookie=new Cookie("lastTime",newDate);
//设置cookie存储时长
cookie.setMaxAge(60*60*24*30);
//发送cookie
resp.addCookie(cookie);
flag=true;
resp.getWriter().write("<h1>您是第一次登录!</h1>");
}
}
}
10.JSP
10.1概述
jsp-java Server Page:java服务器端页面
10.2原理
jsp本质是一个Servlet
10.3脚本
就是定义了JSP中java代码的书写方式
<% 代码 %>
:定义java代码,相当于定义在Servlet的service方法中<% ! 代码 %>
:定义java代码,相当于定义在Servlet成员的位置,成员变量,成员方法<%= 代码 %>
:输出语句:使用JSP的内置对象-out(后面讲)
10.4内置对象
概述:
直接在JSP页面中,不需要获取和创建,可以直接使用的对象
分类:
1.request;
2.response;
3.sesssion;
4.out;
5.page;
6.application;
7.pageContext;
8.config;
9.exception
内置对象名 | 真实数据类型 | 作用 |
---|---|---|
request | HttpServletRequest | 一次请求中共享数据 |
response | HttpServletResponse | 响应对象 |
session | HttpSession | 一次会话中共享数据 |
out | JSPWriter | 输出对象,输出数据到当前页面 |
page | Object | 当前页面对象 |
application | ServletContext | 所有用户间的共享数据 |
pageContext | PageContext | 当前页面共享数据,通过该对象可以获取其他8个内置对象 |
config | ServletConfig | servlet配置对象 |
exception | Throwable | 只有异常页面有该对象 |
**注意事项:**response.getWriter().write()和out对象,web机制在页面输出时会先考虑response缓冲区
10.5Session
**1.概述:**服务器端会话技术-HttpSession
2.功能:
- 获取HttpSession对象
- request.getSession()
- 使用HttpSession对象
- void seSetAttribute(String name ,Object obj):存储数据
- **Object getAttribute(String name)😗*通过参数名获取参数值
- **void removeAttribute(String name)😗*通过移除参数名删除数据
3.原理:
session的实现依赖于Cookie
第一次发送请求,服务器会创建Session对象,并设置一个唯一的id属性,并在响应时,将Session的id存入到响应头:set-cookie:JSESSIONID=id属性值
第二次发送请求,
cookie中就会有对应的Session id,web服务器读到头信息后,就会将两次请求的Session对象指向同一个Session
4.注意事项:
1.客户端关闭之后,再次开启客户端获取的Session对象是同一个吗?
-
默认情况下,因为客户端关闭,会话就会结束,进而导致Cookie被清空
-
如果需要相同,我们可以设置cookie来实现:seMaxAge()
package org.wdit.session; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; /* * 练习:显示上一次登录时间*/ //注解方式配置Servlet @WebServlet("/session1" ) public class SessionDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取session对象 HttpSession session = req.getSession(); //设置Cookie存活时长 Cookie cookie=new Cookie("JSESSIONID",session.getId()); cookie.setMaxAge(60*60); resp.addCookie(cookie); System.out.println(session); } }
2.服务器重启后,两个会话的Sesssion是同一个吗?
- 因为Session对象会被清空,所以很难相同,但又不不想因为重启服务器而丢失ssession数据
- 解决:Session的钝化和活化 Tomacat可以自动完成Session的钝化和活化
- 钝化:将seesion对象序列化到磁盘
- 活化:在服务器启动后,将session数据文件反序列成Session对象
- 解决:Session的钝化和活化 Tomacat可以自动完成Session的钝化和活化
3.Session什么时候被销毁?
- 服务器关闭
- session对象调用invalidate():把自己杀死
- session默认失效时间30分钟,tomcat–安装目录–config----web.xml
4.特点:
- Session用于存储一次会话中多次请求的数据,存储在服务器端
- Session可以存储任意类型的数据,任意大小的数据
5.Session和Cookie的区别
Sesssion存储量大,任意类型
10.6登陆案例优化
1.将验证码的实际内容存储到Session对象中进行共享
2.将错误信息显示在对应标签后
10.7JSP指令
1.用于配置jsp页面 ,导入文件
2.格式:<%@指令名称 属性名1=属性值1 属性名2=属性值2…%>
3.分类:
- page:配置JSP页面
- include:页面包含()
- taglib:导入资源,后面学习JSTL标签就需要使用指令导入
4.page指令:
- contentType:等同于response.setContentType(),设置响应消息的MIME类型,及编码格式。并且可以设置当前 JSP的编码格式(使用高级开发工具才有的功能)
- **pageEncoding:**当前页面编码集
- **language:**java
- **buffer:**缓冲区大小
- **import:**导包
- **erorPage:**当前页面报错,会自动跳转至该属性中指定的页面
- **isErrorPage:**标识当前页面是否是错误页面,如果为true,则可使用Exception,否则不可以使用exception内置对象
5.taglib指令
-
我们用于引入标签库,后面我们学习JSTl会用到
<%@ taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
- prefix:前缀,自定义的
10.8MVC开发模式
早期没有JSP,开发使用Servlet,response输出标签数据,工作量巨大的。后来JSP出现简化了Servlet的开发,开发人员开始过度使用JSP,导致前后端无法分离,并且代码结构混乱,阅读性也非常的差,为了解决这个问题,java开发就借鉴了MVC开发模式,具体的规定了什么代码写在什么位置
1.MVC
- M:Model模型 JavaBean
- 完成具体的业务操作:比如查询数据库,封装对象等
- V:view视图 JSP
- 展示数据
- C:Controller控制器Servlet
- 获取用户请求输入(请求数据)
- 调用模型
- 将数据交给视图层展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u4u5VYLo-1616838285611)(E:\JAVA上课笔记\img\image-20210304202526308.png)]
2.优点:
1.降低耦合性,使代码便于维护
2.复用性高
3.缺点:
1.使架构变得复杂,对程序员要求有所提高
10.9 EL表达式
1.概述:EL-Expression Language表达式语言,JSP本身支持EL表达式
2.作用:替换 和简化页面中的Java代码
3.语法:${表达式}
4.使用:
1.运算
-
算术运算符:+,-,*,/,%
-
比较运算符:==,!=
<h3>算术运算符</h3> ${1+2}<br> ${1-2}<br> ${1/2}<br> ${1*2}<br> ${1%2}<br> <h3>逻辑运算符</h3> ${3>4 && 5<6}<br> ${3>4 and 5<6}<br>
-
逻辑运算符:&&(and),||(or),!(not)
-
空运算符:empty,用于判断字符串,集合,数组对象是否为null并且长度是否为0
2.获取值
-
EL表达式只能从域对象中获取值
-
pageScope---->pageContext
-
requestScope—>Request
-
sessionScope—>session
-
applicationScope—>application
-
比如:${requestScope.name}
-
${属性名}:省略域对象,它的取值会按照域的大小从小到大依次去寻找
10.10隐式对象
pageContext:通过这个对象。我们可以获取到其他八个JSP内置对象,再通过request对象ContextPath
${pageContext.request.contextPath}
10.11JSTL标签
1.概述:Java Server pages Standarded Tag Library-JSP标准标签库
2.作用:替换和简化页面Java代码
3.使用:
1.导包
2.使用page指令引入标签库
3.使用标签
4.if标签
- 属性:
- test:必须属性,接受boolean表达式
- 如果true,显示标签体内容,false,则不显示
- 一般情况下test属性结合EL表达式一起使用
- test:必须属性,接受boolean表达式
- 注意:if标签没有else,如果要写else,则需再写一个C:if标签
5.choose
1.域中存储一个值
2.使用<C:choose>
3.在<C:choose>
中使用<C:when>
------case
- test:判断域中的值与当前case值的关系
- true:显示
<C:when>
标签内容 - false:继续向下比较,直到都不匹配,显示
<C:otherwise>
标签内容
- true:显示
<%@ taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: LENOVO
Date: 2021/3/4
Time: 21:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>choose标签</title>
</head>
<body>
<%
request.setAttribute("month",1);
%>
<c:choose>
<c:when test="${month==1 or month==2 or month==3}">第1季度</c:when>
<c:when test="${month==4 or month==5 or month==6}">第2季度</c:when>
<c:when test="${month==7 or month==8 or month==9}">第3季度</c:when>
<c:when test="${month==10 or month==11 or month==12}">第4季度</c:when>
</c:choose>
</body>
</html>
6.foreach
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="C" uri="http://java.sun/jsp/jstl/core" %>
<%@ taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: LENOVO
Date: 2021/3/4
Time: 22:07
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>
<%--for(int i=0;i<100;i++)
属性:
1.begin:开始值
2.end结束值(包含)
3.var:临时变量
4.step:步长
5.varStatus:循环状态对象
6.index:索引从0开始
7.count:循环次数,从1开始
练习:打印1-100中所有奇数
2.遍历容器
for(String s:StringList)
属性:
1.items:容器对象--list集合---StringList
2.var临时变量----s
3.varStatus:循环状态对象
index:
count:循环次数
--%>
<c:forEach begin="1" end="100" step="2" varStatus="s" var="i">
${i}-----${s.index}---${count}<br>
</c:forEach>
<%
List list=new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("stringList",list);
%>
<c:forEach items="${stringList}" var="s" varStatus="vs">
${s.index}-----${vs.count}----${s}
</c:forEach>
</body>
</html>
动态展示信息
<%@ taglib prefix="c" uri="http://java.sun/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="org.wdit.pojo.User" %>
<%@ page import="java.util.List" %><%--
Created by IntelliJ IDEA.
User: LENOVO
Date: 2021/3/4
Time: 22:31
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>
<%
List<User> list=new ArrayList<>();
list.add(new User(1,"admin","admin"));
list.add(new User(1,"hx","123456"));
list.add(new User(1,"hx","admin"));
request.setAttribute("list",list);
%>
<table border="1" width="600",align="center">
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
</tr>
<c:forEach items="${list}" var="user" varStatus="s">
<c:if test="${s.count%2==0}">
<tr bgcolor="#faebd7">
<td>${user.id}</td>
<td>${user.usename}</td>
<td>${user.password}</td>
</tr>
</c:if>
<c:if test="${s.count%2!=0}">
<tr bgcolor="#f0ffff">
<td>${user.id}</td>
<td>${user.usename}</td>
<td>${user.password}</td>
</tr>
</c:if>
</c:forEach>
</table>
</body>
</html>
11.过滤器
11.1概述:
1.概述:当访问服务器资源时,过滤器可以将请求拦下,进行一些特殊的功能
2.作用:一般用于完成通用的操作,比如登录操作,统一编码处理,过滤敏感字符
11.2快速入门
步骤:
1.定义一个类,实现接口Fileter
2.复写方法
3.配置拦截路径
演示案例:
先创建一个类,实现Fileter接口,启动服务器,如果没有放行代码,则JSP内容将不会给展示
package org.wdit.fileter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器被执行");
}
@Override
public void destroy() {
}
}
11.3执行流程
package org.wdit.fileter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//对请求信息的处理
System.out.println("过滤器被执行1");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//响应信息的处理
System.out.println("过滤器2被执行");
}
@Override
public void destroy() {
}
}
执行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BkDIL00G-1616838285611)(E:\JAVA上课笔记\img\image-20210305174849506.png)]
为什么会这样?因为过滤器是对访问数据和响应数据进行处理的,所以访问前,过滤会执行一次,处理request中的对象,jsp页面执行后,过滤器会对response数据进行处理
有一点需要注意的是,过滤器再次执行就从放行语句后开始执行
11.4过滤器的配置:(只讲注解方式)
-
拦截路径配置
1.具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器资源才会被执行
2.拦截目录:/user/* 访问user下的所有资源时,过滤器都会执行
3.后缀名拦截:*.jsp 访问所有后缀名为jsp时,过滤器都会被执行
4.拦截所有资源:/* 访问所有资源时,过滤器都会被执行
-
拦截方式配置:资源被访问的方式:直接访问,转发等
1.注解配置:
- 设置dispatcherTypes属性
- REQUEST:默认值,浏览器直接请求资源
- FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源:jsp中配置
- ASYNC:异步访问资源
- 设置dispatcherTypes属性
11.5过滤器链
这里我们只需了解执行顺序即可
*执行顺序:如果有两个过滤器:1,2
1.过滤器1
2.过滤器2
3.资源被执行
4.过滤器2
5.过滤器1
- 过滤先后顺序:按照各类字符串的比较顺序。xml配置按照配置先后
二阶段综合练习:图书管理系统
1.三层架构
三层架构也是软件设计代码架构,与MVC类似,学完三层架构,再结合MVC就可以写出比较标准的代码
三层架构将软件分为了三层:
1.表示层:用户看到的界面,用户可以通过界面上的组件和服务器进行交互
2.业务逻辑层:用来处理业务逻辑,不做具体实现
3.数据访问层:操作数据,存储文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qpV4yBj-1616838285612)(E:\JAVA上课笔记\img\image-20210304231532428.png)]
2.准备工作
1.创建空project–>添加Module–>add…---->web—>WEB-INF
2.导入jar包,配置,工具类
- mysql连接驱动
- 连接池
- JdbcTemplate
- jstl
- BeanUtils.jar
- druid.properties
- JDBCUtils
3.将静态资源考入到web目录下
4.准备数据库
删除选中
3.分页查询
分析:
1.总记录数(Int totalCount):服务器可以自行查出,不用客服端传递数据
2.总页数(interesting totalPage):服务器无法自行完成,需要客户端传递一个参数:rows
3.每页的数据List
4.当前页码(int currentPage):需要客户端提供给服务器
5.分页查询语句:limit startindex,rows
-
startindex-开始索引:(currentPage-1)*rows
-
rows-查几条
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTp5wlSY-1616838285612)(E:\JAVA上课笔记\img\image-20210305141635118.png)]
4.组合条件查询
1.如何采用统一的方式进行条件拼接:
先定义一个模板 :
String sql=” select *from book where 1=1 “
后面我们可以根据用户的输入选择拼接查询条件
sb.append("and b_user=? ")
2.组合条件查询最终返回什么结果?
PageBean对象
5.上传文件
#控制台中文乱码处理
1.Tomcat设置面板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PsYtbQ1o-1616838285613)(E:\JAVA上课笔记\img\image-20210227230937290.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9mNGD48w-1616838285613)(E:\JAVA上课笔记\img\image-20210227231041475.png)]
2.file–settings
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OhvDVIaN-1616838285614)(E:\JAVA上课笔记\img\image-20210227231158098.png)]
3.help—Edit Custom VM Options
为什么会这样?因为过滤器是对访问数据和响应数据进行处理的,所以访问前,过滤会执行一次,处理request中的对象,jsp页面执行后,过滤器会对response数据进行处理
有一点需要注意的是,过滤器再次执行就从放行语句后开始执行
11.4过滤器的配置:(只讲注解方式)
-
拦截路径配置
1.具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器资源才会被执行
2.拦截目录:/user/* 访问user下的所有资源时,过滤器都会执行
3.后缀名拦截:*.jsp 访问所有后缀名为jsp时,过滤器都会被执行
4.拦截所有资源:/* 访问所有资源时,过滤器都会被执行
-
拦截方式配置:资源被访问的方式:直接访问,转发等
1.注解配置:
- 设置dispatcherTypes属性
- REQUEST:默认值,浏览器直接请求资源
- FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源:jsp中配置
- ASYNC:异步访问资源
- 设置dispatcherTypes属性
11.5过滤器链
这里我们只需了解执行顺序即可
*执行顺序:如果有两个过滤器:1,2
1.过滤器1
2.过滤器2
3.资源被执行
4.过滤器2
5.过滤器1
- 过滤先后顺序:按照各类字符串的比较顺序。xml配置按照配置先后
二阶段综合练习:图书管理系统
1.三层架构
三层架构也是软件设计代码架构,与MVC类似,学完三层架构,再结合MVC就可以写出比较标准的代码
三层架构将软件分为了三层:
1.表示层:用户看到的界面,用户可以通过界面上的组件和服务器进行交互
2.业务逻辑层:用来处理业务逻辑,不做具体实现
3.数据访问层:操作数据,存储文件
[外链图片转存中…(img-9qpV4yBj-1616838285612)]
2.准备工作
1.创建空project–>添加Module–>add…---->web—>WEB-INF
2.导入jar包,配置,工具类
- mysql连接驱动
- 连接池
- JdbcTemplate
- jstl
- BeanUtils.jar
- druid.properties
- JDBCUtils
3.将静态资源考入到web目录下
4.准备数据库
删除选中
3.分页查询
分析:
1.总记录数(Int totalCount):服务器可以自行查出,不用客服端传递数据
2.总页数(interesting totalPage):服务器无法自行完成,需要客户端传递一个参数:rows
3.每页的数据List
4.当前页码(int currentPage):需要客户端提供给服务器
5.分页查询语句:limit startindex,rows
-
startindex-开始索引:(currentPage-1)*rows
-
rows-查几条
[外链图片转存中…(img-PTp5wlSY-1616838285612)]
4.组合条件查询
1.如何采用统一的方式进行条件拼接:
先定义一个模板 :
String sql=” select *from book where 1=1 “
后面我们可以根据用户的输入选择拼接查询条件
sb.append("and b_user=? ")
2.组合条件查询最终返回什么结果?
PageBean对象
5.上传文件
#控制台中文乱码处理
1.Tomcat设置面板
2.file–settings
3.help—Edit Custom VM Options
版权声明:本文标题:JSP+Servlet+JDBC的世界等你来 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1729423928a1200730.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论