---Java的开发环境搭建
---Java的基础语法
---Java的面向对象
---数组
---常用类
---异常
---集合
---多线程
---IO流
---反射机制
---注解Annotation
--Tomcat(WEB服务器)
--jetty(WEB服务器)
--JBOSS(应用服务器)
--WebLogic(应用服务器)
--WebSphere(应用服务器)
-应用服务器实现了JavaEE的所有规范。(JavaEE有13个不同的规范)
-Web服务器只实现了JavaEE中的Servlet+JSP两个核心的规范
应用服务器是包含WEB服务器的
apache官网地址:https://www.apache.org/
tomcat官网地址:https://tomcat.apache.org
tomcat只实现了:Servlet+JSP规范
tomcat是Java语言写的
bin:存放服务器的命令文件存放的目录,比如;服务器的打开可重起
conf:配置文件
lib:核心程序目录jar包
logs:日志目录,启动,等信息都会在这个目录生成日志文件
temp:临时目录。临时文件
webapps:web应用
work;用来存放JSP文件翻译之后的文件
bin目录下有一个文件:startup.bat
xxx.bat文件是windows操作系统专用的,bat文件是批处理文件,这种文件可以编写大量的Windows的dos命令,然后执行bat文件就相当于批量的执行dos命令
start.sh这个文件在Windows当中无法执行,在Linux环境中可以使用。在Linux环境下可以使用,在Linux环境下能够执行的是shell命令,
大量的shell命令编写在shell文件当中,然后执行这个shell文件可以批量的执行shell命令。
在dos命令窗口中输入startup.bat来启动tomcat服务器
实现一个最基本的WEB应用(这个WEB没有Java小程序)
第一步:找到CATALINA_HOME\webapps目录
? ? ? ? ? ? ? ?应为所有的webapp都要放到webapp目录下
第二步:在CALINA_HOME\webapps目录下新建一个子目录,起名:oa
? ? ? ? 这个目录名就是你这个webapp的名字
第三步:在oa目录下新建资源文件,例如index.html
? ? ? ? ? 编写index.html文件内容
第四步:启动Tomcat服务器
第五步:打开浏览器,在浏览器地址栏上输入这样的url
? ? ?http://127.0.0.1:8080/oa/index.html
多个层级也没有关系,正常访问即可
注意:我们目前前端上的路径都以“/”开始,都是加项目名的
一个路径是一个资源:这个资源可能是静态的资源也可能是动态的资源(Java小程序)
后端到底要执行哪个Java小程序,取决于你的前端浏览器发送的请求路径。
一个路径对应一个Servlet程序
对于一个动态的web应用来说,一个请求和响应的过程有多少个角色参与,角色和角色之间有多少个协议
有哪些角色:(在整个BS结构的系统当中,有哪些人参与进去了)
。浏览器软件的开发商
。WEB Server的开发团队
。DB Server的开发团队
。webapp的开发团队
JavaEE规范之一Servlet规范
WEB Server和webapp解耦合
browser和WEBServer之间有一套传输协议:HTTP协议。(超文本传输协议)
webapp开发团队和DB Server之间有一套JDBC规范
步骤:
①在webapps目录下新建一个目录,起名crm(这个crm就是webapp的名字)。当然,也可以是其他目录,名字自拟
?注意:crm就是这个webapp的根
②在webapp的根下新建一个目录:WEB-INF
注意:这个目录的名字是Servlet规范中规定的,必须全部大写,必需一摸一样
③在WEB-INF目录下新建一个目录:classes
注意:这个目录的名字必须全是小写。这也是Servlet规范中规定的。另外这个目录下一定存放的是Java程序编译之后的
class文件(这里存放的是字节码文件)
④在WEB-INF目录下新建一个目录:lib
注意:这个目录不是必须的。但如果是一个webapp需要第三方的jar包的话,这个jar包要放到这个lib目录下,这个目录的名字也不能随意编写,
必须全部是小写的lib。例如Java语言连接数据库的数据库驱动jar包,那么,jar包就一定要放到lib目录下
⑤在WEB-INF目录下新建一个文件:web.xml
注意:这个文件是必须的,这个文件名必须叫做web.xml。这个文件必须放在这里。一个合法的webapp,web.xml文件是必须的,这个web.xml文件
就是一个配置文件,在这个配置文件中描述了请求路径和Servlet类之间的对照关系。
这个文件最好从其他的webapp中拷贝,最好别手写。
⑥编写一个Java程序,这个小Java程序也不能随意开发,这个小程序必须实现Servlet接口
这个Servlet接口不在JDK中(应为Servlet不是JavaSE了。Servlet属于JavaEE,是另外一套类库)
Servlet接口(Servlet.class文件)是Oracle提供的
Servlet接口是JavaSE的规范中的一员
Tomcat服务器实现了Servlet规范,所以Tomcat服务器也需要使用Servlet接口。Tomcat服务器中应该有这个接口,Tomcat服务器
的CATALINA_HOME\lib目录下有一个servlet-api.jar,解压这个jar包后,你会看到里面有一个Servlet.class文件
重点:JakartaEE9开始,Servlet接口名就变了:Jakarta.servlet.Servlet
注意:编写这个小程序的时候,Java源代码你愿意放在那里就放在那里,位置无所谓,你只需要将Java源代码编译之后的class文件放到classes目录下即可
⑦编译我们编写的Java代码
⑧将以上编译之后的文件拷贝到WEB-INF\classes目录下
⑨在web.xml文件中编写配置信息,让“请求路径”和“”
⑩启动Tomcat服务器,然后打开浏览器
浏览器上编写的路径太复杂,可以使用超链接。(非常重要:惠HTML页面只能放到WEB-INF目录外面)
以后不需要我们编写main方法了,tomcat服务器负责调用main方法,tomcat服务器启动时执行的就是main方法。我们Java程序员
只需要编写Servlet接口的实现类,然后将其注册到web.xml文件中
将CATALINA_HOME/conf/logging.properties文件中的内容修改如下:
java.util.logging.ConsoleHandler.encoding=GBK
总结一下:
? ? ? 一个合法的WEBAPP目录结构应该是怎样的?
--webapp的根
? ? ? ? ? ? ? ? WEB-INF
??? ? ? ? classes(存放字节码)
? ? ? ? ? ? ? ? ? ? ? lib(第三方jar包)
? ? ? ? ? ? ? ? ? ? ? ?web.xml(注册Servlet)
? ? ? ? ? ? ? ? html
?? ?css
?? ?javascript
?? ?image
?? ?...
public void service(ServletRequest request,ServletResponse response)
? ? throws ServletException,IOEception{
response.setContentType("text/html");
PrintWriter out=response.getWriter();
//编写JDBC代码来链接数据库
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
?try{
? //注册驱动
Class.forName("com.mysql....");
//获取链接
String url="jdbc:mysql://localhost:8080/student";
String user="root";
String password="root";
conn=DriverManger.getConnection(url,user,password)
//获取预编译的数据库操作对向
String sql="select * from stu";
ps=conn.prepareStatement(sql);
//执行SQL语句
rs=ps.executeQuery();
//处理结果集
while(rs.next()){
String no-rs.getString("no");
String name=rs.getString("name");
? ? ? }
}catch( Exception e){
? ? ?e.printStackTrace();
}finally{
? ? //释放资源
? ? ? ? ? ?if(rs!=null){ rs.close();}?
? ? ? ? ? ?if(conn!=null){ conn.close();}
? ? ? ? ? ?if(ps!=null){ps.close();}
? ? ? ?}
}
Servlet是Java程序,所以在Servlet中完全可以编写JDBC代码连接数据库
在一个WEBAPP中去链接数据库,需要将驱动jar包放到WEB-INF/lib目录下
Servlet对象的生命周期
1.什么是Servlet的生命周期?
? Servlet对象什么时候被创建,神魔时候被销毁。
?Servlet对象创建了几个?
?Servlet对象的生命周期表示:一个 Servlet对象从出生在最后死亡,整个过程是怎样的。
?Servlet对象由随来维护?
?Servlet对象的创建,对象上方法的调用,对象最终的销毁,Javaweb程序员是无权干预的。
?Servlet对象的生命周期是由Tomcat服务器全权负责的。
Tomcat服务器通常我们又称web兼容器。(WEB Container)
web容器来管理 Servlet对象的死活。
我们自己new的 Servlet受web容器的管理吗?
我们自己new的 Servlet对象是不受web5容器管理的
web容器自己创建的 Servlet对象都会被放到一个集合中(HashMap),只有放到这个集合中的 Servlet才能被web容器管理
自己new 的不在容器里
。在 Servlet中提供一个无参的构造方法,启动服务器的时候看看构造方法是否执行。
。经过测试得出结论:默认情况下,服务器在启动的时候 Servlet对象并不会被实例化。
。这个设计是合理的,用户没有发送请求之前,如果提前创建出来所有的 Servlet对象,必然是耗费内存的,并且创建出来的 Servlet如果一直
没有用户访问,也没必要创建
怎末让启动服务器的时候创建 Servlet对象呢?
在 Servlet标签中添加<local-on-startup>子标签,在该子标签中填写整数,越小的整数说明优先级越高。
?Servlet对象的生命周期?
?Servlet更像是人的一生:
?Servlet的无参构造方法执行:标志着你已经出生了
?Servlet对象的init方法的执行:标志着你正在接受教育
?Servlet对象的service方法的执行:标志着你已经开始工作了
?Servlet对象的destory方法的执行:标志着临终。
?Servlet类中方法的调用次数?
构造方法只执行一次。
init方法只执行一次。
service方法:用户发送一次请求则执行一次,发送N次执行N次
destroy方法只执行一次。
500报错
注意:500是一个HTTP协议的错误状态码
500一般是Java程序出现了异常
如果没有无参构造方法,会导致出现500错误,无法实例化 Servlet对象
所以,一定要注意:在 Servlet开发中不建议程序员来定义构造方法,应为定义不当,一不小心就会导致无法实例化 Servlet对象
思考: Servlet的无参构造方法是在对象第一次创建时候执行,并且只执行一次。init方法也是在对象第一次创建的时候执行,并且
只执行一次。那么这个无参数构造方法可以替代调init方法吗?
不能
?Servlet规范中有要求,作为Javaweb程序员,编写 Servlet类的时候,不建议手的编写构造方法,很容易让无参数构造方法消失,这个操作
可能会导致 Servlet对象无法被实例化。所以init方法是有必要存在的
init。service。destroy方法中使用最多的是哪个方法?
使用最多的就是service方法,该方法是必须实现的,应为它是处理用户请求的核心方法。
什么时候使用init方法呢?
init方法使用的很少。
通常在init方法做初始化操作,并且这个初始化操作只需要执行一次。例如:初始化数据库连接池,初始线程池......
什么时候使用destroy方法呢?
destroy方法使用的也很少。
通常在该方法中进行资源关闭。马上对象要销毁了,还有什么要关闭,还有啥要保存的赶紧保存。
项目构建工具:http://maven.apache.org/
Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
? 提供了一套标准化的项目结构
提供了一套标准化的构建流程(编译,测试,打包,发布)
提供了一套依赖管理机制
依赖管理其实就是管理你项目所依赖的第三方jar包和插件等
1.Maven使用标准的坐标配置来管理各种依赖
2.只需要简单的配置就可以完成依赖管理
标准化的项目结构
所有IDE使用Maven构建的项目结构完全一样,所有IDE创建的maven项目可以通用
标准化的构建流程:
Maven--->编译--->测试--->打包--->发布
Maven提供了一套简单的命令来完成项目的构建
Maven仓库:①本地仓库:自己计算机上的一个目录
②中央仓库:maven团队维护的全求唯一的仓库
③远程仓库(私服):一般由公司团队搭建的私有仓库
Maven常用命令:
compile:编译
clean:清理
test:测试
package:打包
install:安装
maven坐标?
maven坐标是资源的唯一标识
使用坐标来定义项目或引入项目中需要的依赖
maven坐标主要组成
groupld:定义当前maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
artifactld:定义当前maven项目名称(通常是模块名称,例如order-service、goods-service)
version:定义当前项目版本号
以后所有的Servlet类都要继承一个抽象类构成的适配器,将这个适配器实现Servlet接口然后重写五种方法,哪一个方法常用就将其写成抽象方法,
父类原始的init方法final了,我子类没有办法重写init方法了
如果这个时候还是想要重写这个init方法该怎末办呢?
* 1.SevletConfig是什么?
* jakerta.sevlet.Sevlet.COnfig
* 是一个接口
* 2.是谁实现了这个接口?
*ServletConfig是:org.apache.catalina.core.StandardWrapperFacade@1cc25be
* WEB服务器实现了
* 3.一个Servlet对象中有一个ServletConfig对象。(Servlet和ServletConfig对象是一对一)
* 100个Servlet,就应该有100个ServletConfig对象
* 4.ServletConfig对象是谁创建的?创建了Servletconfig对象
* Tomcat服务器(web服务器)创建了ServletConfig对象
* 在创建ServletConfig对象的时候,同时创建ServletConfig对象
* 5.ServletConfig接口到底是干啥的?到底有森马用?
* ServletConfig:Servlet对象那个的配置信息对象
*一个ServletConfig对象就有一个配置信息对象()
* ?<servlet>
? ? ? ? <servlet-name>ConfigTestSevlet</servlet-name>
? ? ? ? <servlet-class>com.ConfigTestSevlet</servlet-class>
? ? </servlet>
? tomcat小猫咪解析web.xml文件,将web.xml文件中的<servlet></servlet>标签中的配置信息自动包装到ServletConfig对象中
在用户发送第一次请求时创建
? ?6.ServletConfig接口中有哪些方法?
8.Servletconfig接口中有4个方法:
?* ? ?1.public String GteInitParameter(string name)
?* ? ? 2. Enumeration<String> initParameterNames getInitParameterNames();
?* ? ? 3.public ServletContexxt getServletContext();
?* ? ?4.public string getServletName();
?* 以上的4个方法也可以使用this去调用
? ?* <init-param>
? ? ? ? ? ? <param-name>driver</param-name>
? ? ? ? ? ? <param-value>com.mysql.jdbc.Driver</param-value>
? ? ? ? </init-param>
? ? ? ? <init-param>
? ? ? ? ? ? <param-name>url</param-name>
? ? ? ? ? ? <param-value>jdbc:mysql://localhost:3306/student</param-value>
? ? ? ? </init-param>
? ? ? ? <init-param>
? ? ? ? ? ? <param-name>user</param-name>
? ? ? ? ? ? <param-value>root</param-value>
? ? ? ? </init-param>
? ? ? ? <init-param>
? ? ? ? ? ? <param-name>password</param-name>
? ? ? ? ? ? <param-value>root</param-value>
? ? ? ? </init-param>
? ? ? ? * 以上<servlet></servlet>标签中的<init-parm>是初始化参数。这个初始化参数信息会自动被小猫咪封装到ServletConfig对象中。
?* * */
public class ConfigTestSevlet extends GenericServlet ?{
? ? @Override
? ? public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//获取sevletconfig对象
? ? ? ? ? ? servletResponse.setContentType("text/html");
? ? ? ? ? ? PrintWriter out=servletResponse.getWriter();
? ? ? ? ? ? //获取Sevletcofig对象
? ? ? ? ServletConfig config=this.getServletConfig();
? ? ? ? //输出该对象
? ? ? ? out.println("ServletConfig是:"+config.toString());
? ? ? ? //获取<Servlet-name>
? ? ? ? String servletName=config.getServletName();
? ? ? ? out.println("<br>");
? ? ? ? out.println("<servlet-name>"+servletName+"</servlet-name>");
? ? ? ? //通过Servletconfig对象的两个方法,可以获取到WEB.xml文件中的初始化参数配置信息
? ? ? ? Enumeration<String> initParameterNames = config.getInitParameterNames();
? ? ? ? //遍历集合
? ? ? ? out.print("<br>");
// ? ? ? ?while(initParameterNames.hasMoreElements()){
// ? ? ? ? ? ?String parameterName=initParameterNames.nextElement();
// ? ? ? ? ? ?out.print(parameterName);
// ? ? ? ? ? ?out.print("<br>");
// ? ? ? ?}
? ? ? ? //改造
? ? ? ? while (initParameterNames.hasMoreElements()){
? ? ? ? ? ? String parameterName=initParameterNames.nextElement();
? ? ? ? ? ? String parametervar=config.getInitParameter(parameterName);
? ? ? ? ? ? out.print(parameterName+"="+parametervar);
? ? ? ? ? ? out.print("<br>");
? ? ? ? }
? ? ? ?/* //通过初始化参数的name获取value
? ? ? ? ? ?String driver=config.getInitParameter("driver");
? ? ? ? */
? ? }
-------------------------------------------------------------------------------------遍历集合
while(initParameterNames.hasMoreElements()){
// ? ? ? ? ? ?String parameterName=initParameterNames.nextElement();
// ? ? ? ? ? ?out.print(parameterName);
// ? ? ? ? ? ?out.print("<br>");
// ? ? ? ?}
-----------------------------------------------------------------------------------
/*this.getInitParameterNames();
? ? ? ? this.getInitParameter("driver");
? ? ? ? this这里相当于ConfigTestSevlet
? ? ? ? */
Enumeration<String> initParameterNames1 = this.getInitParameterNames();
? ? ? ? while (initParameterNames1.hasMoreElements()){
? ? ? ? ? ? String name=initParameterNames1.nextElement();
? ? ? ? ? ? String varlue=this.getInitParameter("name");
? ? ? ? ? ? out.print(name+"="+varlue);
? ? ? ? ? ? out.print("<br>");
? ? ? ? }
ServletContext接口
怎末获取Servletcontext对象?
1.通过ServletConfig对象获取Servletcontext对象
2.通过this获取
1.servletContext是什么?
ServletContext是一个接口,是Servlet规范中的一员
2.ServletContext是tomcat实现的
3.ServletContext对象是在WEB服务器启动的时候创建的
ServletContext对象是WEB服务器创建的
对于一个webapp来说,ServletContext对象只有一个
ServletContext对象爱服务器关闭的时候销毁
4.ServletContext原理?
Servlet对象的环境对象。Servlet的上下文对象
ServletContext对象其实对应的就是整个web.xml文件。
放在ServletContext对象当中数据,所有Servlet一定是共享的。
比如:一个教室中的空调是所有学生共享的,教师是共享的
tomcat是一个容器,一个容器当中可以放多个webapp,一个webapp对应一个ServletContext对象。
ServletContext接口中有哪些常用方法?
public String getInitParameter(String name);//通过name获取value
public Enumeration<String> getInitParameterNames();//获取所有初始化参数的name
<!--上下文初始参数,以下的配置信息需要通过Servletcontext来来调用-->
? ? <context-param>
? ? ? ? <param-name>pageSize</param-name>
? ? ? ? <param-value>10</param-value>
? ? </context-param>
? ? <context-param>
? ? ? ? <param-name>startIndex</param-name>
? ? ? ? <param-value>0</param-value>
? ? </context-param>
? ? 以上的配置信息是应用级的配置信息,一般一个项目中共享的配置信息会放到以上的标签中。
? ? 如果你的配置信息只是想给某一个servlet作为参考,那么你配置到servlet标签当中即可,使用servletConfig对象来获取
? ??
获取context path(获取应用上下文的根)
?//在Java源代码当中,不要将应用的根路径写死,应为你永远都不知道这个应用在最终部署的时候,起一个什么名字?
String contextPath=context.getContextPath();
//获取文件的绝对路径
String realPath=this.ServletContext.getrealPath("这里写要得到路径的文件名");
//通过ServletContext对象也是可以记录日志的
public void ?log(String message);
public void log(String message,Throwable t);
?*/
ServletContext对象还有另一个名字:应用域(后面还有:请求域,会话域)
如果所有的用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中
为什么是所有用户共享的数据?
不是共享的没有意义,应为ServletContext这个对象只有一个。只有共享的数据放进去才有意义。
为什么数据量要小?
应为数据量比较大的话,太占堆内存,并且这个对象那个的生命周期比较长,服务器关闭的时候,这个对象才会被销毁。大数据量会影响服务器的性能。占用内存较小的数据量可以考虑放进去。
为什么这些共享数据很少的修改,或者几乎不修改?
所有用户共享数据,如果涉及到修改操作,必然会存在线程并发所带来的安全问题。所以放在ServletContext对象中的数据一般都是只读的。
//数据量小,所有用户共享。又不修改,这样的数据放到ServletContext这个应用域中,会大大提升效率。应为应用域相当于一个缓存,放到缓存中的数据,下次在用的时候,不需要从数据库中再次获取,大大提升了执行效率。
//存(怎么向ServletContext应用域中存数据)
public void setAttribubute(String name,Object value);//map.put(k,v)
//取(怎么从ServletContext应用域中取数据)
public Object getAttribute(String name);//object v=map.get(k)
//删(怎么删除ServletContext应用域中的数据)
public void removeAttribute(String name);//map.remove(k)
以后我们编写Servlet类的时候,实际上是不会去直接继承GenericServlet类的,因为我们是B/S结构的系统,这种系统是基于HTTP超文本传输协议的,在Servlet规范中,提供了一个类叫做HTTPServlet,它是专门为HTTP协议准备的一个Servlet类.我们编写的Servlet类·要继承HttpServlet。()
我们更加便捷
继承结构
jakarta.servlet.Servlet(接口)---->爷爷
jakarta.servlet.GenericServlet implements Servlet(抽象类)----->儿子
jakarta.servlet.http.HttpServlet extends GenericServlet (抽象类)--->孙子
我们以后编写的servlet要继承HttpServlet类
缓存机制?
--堆内存当中的字符串常量池
? ?"abc"先在字符串常量池中查找,如果有,直接拿来用。如果没有则新建,然后再放入字符串常量池
--堆内存当中的整数型常量池。
--连接池
--线程池
--redis
--NoSQL数据库。非关系型数据库。缓存数据库
---------------------------------------------------------------------------
HTTP协议
HTTP:Hyper Text Tranfer Protocol,超文本传输协议,规定了浏览器和服务器之间的数据传输的规则
什么是超文本?
不是普通的文本,比如说流媒体:声音、视频、图片等
特点:1.TCP协议:面向连接,安全
2.基于请求-响应模型的:一次请求对应一次响应
3.HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的
--缺点:多次请求间不能共享数据。Java中会使用会话技术(cookie、session)来解决这个问题
--优点:速度快
HTTP请求数据格式
1.请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本
2.请求头:第二行开始,格式为key:value形式
3.空白行
4.请求体:POST请求的最后一部分,存放请求参数
请求行
? 三部分:
-请求方式(7种):get,post,delete,put,head,options,trace
-uri:统一资源标识符。代表网络中某个资源的名字。但是通过uri是无法定位资源的。
url:统一资源定位符。代表网络中某个资源,同时,通过url是可以定位到该资源的。
URL包括URI
http://localhost:8080/servlet04/index.html-----URL
/servlet04/index.html-----URI
-HTTP协议版本号
HTTP响应数据格式:
1.响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态,OK表示状态码描述
2.响应头:第二行开始,格式为key:value形式
3.空白行
4.响应体:最后一部分。存放响应数据
HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Content-Length: 140
Date: Sun, 17 Jul 2022 01:32:37 GMT
Keep-Alive: timeout=20
Connection: keep-alive
<h1 > from get servlet</h1 > ?</body > </html >
状态码分类
1xx:响应中
2xx:成功(200:🆗客户请求成功,这是我们最想看到的状态码)
3xx重定向:重定向到其他地方,它让客户在发送一个请求以完成整个处理
4xx客户端错误(404:Not Found:请求资源不存在,一般是URL输入有误,或者网站资源被删除了)
5xx服务器端错误(500:Java代码有异常)
404表示访问的资源不存在,通常是因为要么是你路径错了,要么是对应的资源没有启动成功。总之404错误是前端错误
405表示前端发送的请求方式与后端请求的处理方式不一致
比如前端是POST请求,后端的处理方式按照get方式进行处理时发生405
500表示服务器端的程序出现了异常
响应体就是响应正文,这些
到目前为止在form表单中的method属性值为post
其他所有情况一律都是get请求
在浏览器地址栏上输入URL并回车属于get请求
在浏览其上直接点超链接,属于get请求
form表单的method默认属性是get
GET和POST请求的区别?
get在浏览器地址栏上会显示用户数据
post不会在浏览器地址栏上显示用户数据,相对来说比较安全
GET&POST发送请求的数据格式是完全相同的,只不过位置不同,格式都是统一的
get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同
get请求无法发送大数据量
post请求可以发送任何类型的数据。包括普通字符串,流媒体等信息:视频、声音、图片
post请求可以发送大数据量,理论上没有长度限制
W3CZ中这样说:
get请求比较适合从服务器端获取数据
post请求比较适合向服务器端传送数据
get请求是安全的。get请求是绝对安全的。为什么?
应为get请求是为了从服务器得到数据,不会对服务器造成威胁
post请求是危险得。应为该请求向服务器提交数据,如果这些数据通过后门的方式进到服务器中,服务器是很危险的。另外post是为了提交数据,所有一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。
任何一个get请求最终得“响应结果”都会被浏览器缓存起来。在浏览器缓存当中:一个get请求的路径 ?对应 ?一个资源
大部分form表单提交,都是post方式方式,应为form表单要提交大量信息
我们不希望get请求走缓存,怎末办?怎么避免走缓存?我希望每一次这个get请求都去服务器上找资源,我不想从本地浏览器得缓存中取
只要每次get请求不同即可
怎么解决?可以在路径后面加一个每时每刻都在变化得“时间戳”
发送请求后,浏览器会从缓存中找,找不到就冲服务器中重新找
如何判断使用POST||GET?
你这个请求是想获取服务器得数据还是想发送数据给服务器。
如果想从服务器上获取资源,建议使用GET,如果向它发送资源就用post
@WebServlet注解常用属性
name:Servlet名字(可选)
value:配置url路径,可以配置多个
urlPatterns:配置url路径,和value作用一样,不能同时使用
localOnStartup:配置servlet的创建的时机,如果是0或者正数,启动程序时创建;如果是负数,则访问时创建。数字越小优先级越高
模板方法设计模式
什么是设计模式?
解决莫个问题的固定得解决方案(可以重复使用)
GoF设计模式:通常我们所说得23种设计模式
? ? ? 单例模式、工厂模式、代理模式、门面模式、责任链设计模式、观察者模式、
JavaEE设计模式:
? DAO\DTO\VO\PO\pojo
.....
httpServletRequest对象中封装了什么信息?
封装了请求协议的全部内容
最终的Servlet的开发步骤:
①编写一个Servlet类,直接继承HttpServlet
②重写doGet方法或直接重写doPost方法,到底重写谁,Javaweb程序员说了算。
③将Servlet类配置到web.xml文件中。
④准备前端的页面(form表单),form表单中指定请求路径即可。
-------------------------------------------------------------------------
一个web站点的欢迎页面
web.xml文件中做配置
默认访问页面
<welcome-file-list>
? ? ? ? <welcome-file>login.html</welcome-file>
? ? </welcome-file-list>
不要以斜杠开始
访问:http://localhost:8080/servlet06
可以设置多个默认页面,越往上优先级越高,上面加载不出来往下找
<welcome-file-list>
? ? ? ? <welcome-file>page1/page2/page.html</welcome-file>
? ? ? ? <welcome-file>login.html</welcome-file>
? ? </welcome-file-list>
Tomcat服务器的全局欢迎页面时:index.html ?index.htm index.jsp
如果你一个web站点没有设置局部的欢迎页面,
Tomcat服务器就会以index.html ?index.htm index.jsp作为一个web站点的欢迎页面。
默认页面也可以是一个servlet页面
在WEB-INF目录下创建了一个文件,welcome.html
放在WEB-INF目录下的资源是受保护的。在浏览器上不能够通过路径直接访问。所以像html.css.js.image等静态资源一定要放到WEN-INF目录之外
---------------------------------------------------------------------------
HttpServletRequest接口
HttpServletRequest对象是Tomcat服务器创建的。这个对象中封装了Http协议。
用户发送请求的时候,遵循了Http协议,发送的是HTTP的请求协议,服务器将HTTP协议中的信息以及数据全部解析出来,然后服务器把这些信息封装到HttpServletRequest对相中,传给我们Javaweb程序员
javaweb程序员面向HttpServletRequest接口编程就可以获取到请求的信息了。
Request和resquest对象,这两个对象只在当前请求中有效
一次对应一个、两次对应两个
HttpServletRequest接口中的常用方法?
①获取前端浏览器用户提交的数据
? getParameter(String name)
? getParamaterMap()
? ? getParamaterNames()
? (最常用) ? ?getParamaterValues(java.lang.String)
? ?获取value这个一维数组当中的第一个元素。
?
? ?key ? ? ? ? ? ? ? ? ? ? ? ? ? ? value
? ------------------------------
? username ? ? ? ? ? ? ? ? ? ? abc
?userpassword ? ? ? ? ? ? ? ?111
?aihao ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? s
? aihao ? ? ? ? ? ? ? ? ? ? ? ? ? ? h
?aihao ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?tt
request对象实际上又称为“请求域对象”
ServletContext应用域当中绑定数据,就相当于把数据放到了缓存当中,然后用户访问的时候直接从缓存中取,减少io的操作,大大提升系统的性能,所以缓存技术是提高系统性能的重要手段。
ServletContext当中有三个操作域的方法:
void setAttribute(String name, object onj);//向域中绑定数据---map.put("name",obj)
object getAttribute( string ame);//从域中根据name获取数据---map.get("name")
void removeAttribute( string name);//将域当中绑定的数据移除---map.remove("name")
“请求域”对象
比“应用域”对象范围小很多。生命周期短很多。请求域只在一次请求内有效。
请求域对象也有这三个方法:
void setAttribute(String name, object onj);//向域中绑定数据---map.put("name",obj)
object getAttribute( string ame);//从域中根据name获取数据---map.get("name")
void removeAttribute( string name);//将域当中绑定的数据移除---map.remove("name")
只有当用于发送请求的时候,请求域才会创建,请求一次,创建一次。
请求域和应用域
可以将两个servlet放到一次请求中
需要使用servlet当中的转发机制
执行Aservlet之后,跳转到Bservlet
第一步:获取请求转发器对象
//相当于把“/b路径封装到转发器当中”实际上是把下一个跳转的资源的路径告知给Tomcat服务器
request.getRequestDispatcher("/要跳转的的servlet路径")
第二部:调用请求转发器RequestDispatcher的forward的方法
dispatcher.forward(request,response);
//一行代码搞定转发
request.getRequestDispatcher("/要跳转的的servlet路径").forward(request,response);
两个Servlet怎末共享数据?
将数据放到servletsontext应用域当中是可以的,但是应用域范围太大,占用资源太多。不建议使用。
可以将数据放到request域当中,然后Aservlet转发到Bservlet,保证Aservlet和Bservlet在同一次请求当中,这样就可以做到两个servlet,或者多个servlet共享同一份数据。
转发的资源不一定是一个servlet,只要是Tomcat服务器当中的合法资源都可以转发,例如HTML
转发的时候,路径的写法要注意,转发的路径以“/”开始,不加项目名
//uri?username=zhangsan&userpwd=123&sex=1
String username=request.getParameter("username");
//之前一定执行过request.setAttribute("name","value");
Object obj=request.getAttribute("name");
以上两个方法的区别是啥?
第一个:获取的是用户在浏览器1上提交的数据。
第二个:获取的是请求域当中的数据。
关于request对象的常用方法
获取用户的IP地址:
String remoteAddr=request.getRemoteAddr();
System.out.println("客户端的IP地址:"+remoteAddr);
设置请求体的字符集。(该方法是处理POST请求的乱码问题。这种方式并不能解决get请求的)
request.setCharacterEncoding("UTF-8");
响应的时候的乱码问题
respnse.setContentType("text/html;charset=UTF-8");
get请求在请求行上提交数据。
post请求在请求体中提交数据。
get请求乱码问题怎么解决?
get请求发送的时候,数据是在请求行上提交的,不是在请求体当中提交的。
方案一:修改CATALINA_HOME/conf/server.xml配置文件
<Connector port="8080" protocol="HTP/1.1"
? ? ? ? ? ? ?connectionTimeout="20000'
? ? ? ? ? ? ?redirectPort="8443"
? ? 加 ? ? ?URIEncoding="UTF-8"/>
从tomcat8后 URIEncoding的默认值就是"UTF-8"
获取应用的根路径:
String contextPath=request.getContextPath();
//获取请求方式
String method=request.getMethod();
//获取请求的uri
String uri=request.getRequestURI();
**前端发送请求的路径需要加项目名
在一个web应用中应该如何完成资源的跳转
第一种方式:转发
request.getRequestDispatcher("").forword()
第二种方式:重定向
response.sendRedirect("/项目名/b");
二者区别:
转发是一次请求,重定向是两次请求。
转发:是由web服务器来控制的。A资源跳转到B资源,这个动作是TomCat服务器内部完成的
重定向:是由浏览器完成的。具体跳到那个资源是浏览器说了算。
转发和重定向应该如何选择?
如果在一个servlet当中向request域当中绑定了数据,希望从下一个Servlet域里面的数据取出来
,使用转发机制,其余所有请求均采用重定向。(重定向使用较多)
转发会存在浏览器的刷新问题:
servlet注解,简化配置
web.xml文件直接写到类中以注解的方式
servlet3.0之后
开发效率高直在Java类进行标注,web.xml文件体积变小了,一般开发采用注解+配置文件的开发模式
一些不轻易修改的信息在web,xml文件中配置
@webServlet
name:用来指定Servlet的名字,等同于:<servlet-name>
urlPatterns:用来指定Servlet的映射路径。可以指定多个字符串。<url-pattern>
loadOnStartUp:涌来指定在服务器启动阶段是否加载该servlet。等同于<load-on-startup>
value:当注解的属性名是value的时候,使用注解的时候,value属性名是可以省略的
注意:不是必须将所有的属性都写上,需要哪个写那个
注意:属性是一个数组,如果数组中只有一个元素使用该注解的时候,属性值得大括号可以省略12
格式
@webServlet(属性名=属性值,属性名=属性值)
JavaBean:
一个Javabean一般有一套规范:
?①有无参属的构造方法
②属性私有化
③对外提供setter和getter方法
④重写toString()
⑤重写hashCode+eauals
⑥实现Java.io.Serializable接口
解决类爆炸问题?
模板设计方法设计模式
怎末解决类爆炸问题,?
以前的设计是一个请求对应一个servlet类。1000个请求对应1000个servet类。
可以这样做:一个请求对应一个方法。一个业务对应一个servlet类。
处理部门相关业务的对应一个DeptServlet。处理用户相关业务的对应一个UserServlet。处理银行卡卡片业务对应一个CardSerclet.
jsp实际上就是一个servlet。
index.jsp访问的时候,会自动生成index.jsp.java,会自动编译生成jsp.class,那么index.jsp就是一个类。
index.jsp类继承HttpjspBase类继承的是httpservlet。所以index.jsp类就是一个servlet类。
jsp的生命周期和servlet的生命周期完全相同。完全就是一个东西。没有任何区别。
jsp和servlet一样欧式单例的。(假单例)
单例-----一个对象
jsp文件第一次访问的时候是比较慢的,为什么?
第一次比较麻烦:
?要把jsp文件翻译生成Java源文件
Java源文件要编译生成class字节码文件
然后通过class去创建servlet对象
然后调用servlet对象得init方法
最后调用servlet对象的service方法
第二次比较快:
直接调用单例service对象的service方法即可。
JSP是什么?
jsp是Java程序。(jsp本质还是一个Servlet)
JSP是:JavaServer Pages的缩写。(基于Java语言实现的服务器端的页面)
servlet是JavaEE的13个子规范之一,那么jsp也是JavaEE的13个子规范之一。
JSP是一套规范,所有的web容器/web服务器都是遵循这套规范的,都是按照这套规范进行的“翻译”
每一个web容器/web服务器都会内置一个JSP翻译引擎
对JSP调试的时候,还是要直接打开JSP文件对应的Java文件,检查Java代码。
在JSP的基础语法:
在JSP文件中直接编写文字,都会自动被编译到servlet类的service方法的out.write("翻译到这里")
然后被Java程序当作普通字符串打印输出
在jsp文件中编写的HTML css js代码,这些代码对于jsp来说只是一个普通的字符串。但是jsp把这个普通的字符串一旦输出
到浏览器,浏览器就会对HTML css js代码进行执行。展现一个效果。
jsp配置指令解决响应乱码问题
<%@page contentType="text/html;charset=UTF-8"%>
通过page指令来设置响应的内容类型,在内容类型后面进行添加
怎么在JSP中编写Java程序:
<%Java语句%;>---脚本快
在这个符号当中编写的被视为Java程序,被翻译到service方法内部
在<%%>这个符号里面写Java代码的时候相当于在“方法体”中写代码
方法体中可以写什么,不能写什么?
jsp专业注释<%-- ?--%> ?不会被翻译到Java源代码中
!!!!在service方法当中定义的变量不能使用private等访问权限修饰符
方法体当中不能直接编写静态代码块,不能直接编写方法,方法套方法是不允许的。
在service方法当中编写代码是有顺序的,顺序是自上而下。
在一个JSP中<%%>可以出现多个
<%!%>
在这个符号当中编写的Java程序会自动翻译到service方法之外。
这个语法很少用:因为在service方法外面写静态变量和实例变量,都会存在线程安全问题。
jsp就是servlet,servlet是单例的,多线程并发的环境下,这个静态变量和实例变量一旦有修改操作,必然会存在线程安全问题
JSP的输出语句:
向浏览器上输出一个Java变量?
调用out.write()方法
<% ?String name="zahngsan";out.write("name="+name);%>
注意:以上代码中的out是JSP的9大内置对象之一。可以直接拿来用。当然,必须只能在service内部使用
JSP既然本质上是一个servlet,那么他们的本质区别是什么?
职责不同:
JSP的是数据的展示(JSP的强项是做数据的展示)
servlet是数据的收集(servlet的强项是逻辑处理,业务处理,然后链接数据库,获取/收集数据)
如果输出的内容中含有“Java代码”,这个时候可以使用以下语法格式:
<%=%>在等号后面编写代码
out.print();
翻译到service方法当中
什么时候使用<%=%>输出呢?
输出的内容含有Java变量,输出的内容是一个动态的内容,不是一个死的字符串。
如果输出的是一个固定的字符串,直接在JSP文件中编写即可
文件的扩展名必须是xxx.jsp吗?
jsp文件的扩展名是可以配置的。不是固定的。
xxx.jsp文件对于小猫咪来说,只是一个普通的文本文件,web容器会将xxx.jsp文件最终生成Java程序,最终会调用的是Java对象相关的方法,真正执行的时候,
jsp文件就没有关系了,
JavaBean符合Javabean规范,具有很强的通用性
JSP指令
作用:指导JSP的翻译引擎如何工作(指导当前的jsp翻译引擎如何翻译JSP文件)
指令包括哪些呢?
include指令:包含指令,在jsp中完成静态包含,很少用了
taglib指令:引入标签库的指令。这个到jstl标签库的时候在学习。
page指令:目前重点学习一个page指令。
指令使用格式:<%@指令名 属性名=属性值 属性名=属性值.....%>
page指令中的常用指令:
content Type-----设置响应类型
session=“true|false”
true表示启用JSP的内置对象session,表示一定启动session对象。没有session对象会创建。
如果没有设置,默认值就是session=“true”
session=“false”表示不启动内置对象session。当前JSP页面中无法使用内置对象session。
pageEncoding=UTF-8表示设置响应编码格式,
import----导包
errorPage="error.jsp"------当页面出现异常后,跳转到error.jsp页面。
出错后的跳转的位置。
JSP的九大内置对象
servlet+jsp
session---->cookie---->EL表达式---->jstl标签---->Filter---->Listener
AjAx-->jQuery---->Vue--->mvc架构模式---->连接池--->SSM---->maven--->git
------------------------------------------------------------------------------------
JSP基础语法总结:
①JSP中直接编写普通字符串---翻译到service方法的out.write("这里")
②<%%>---翻译到service方法内部,里面是一条一条的Java语句
③<%! %>---翻译到service方法之外
④<%=%>---翻译到service方法体内部,翻译为:out.print();
⑤<%@page>
session
用户打开浏览器,进行一系列操作,然后最终将浏览器关闭,这个整个过程叫做:一次会话。会话在服务器端也有一个对应的Java对象,
这个对象就叫做session。一个会话对应N个请求
session和request都是服务器端的Java对象。都在jvm中
不同的语言对这种会话机制都有实现。
session对象最主要的作用是:保存会话状态。
为什么需要session对象来保存会话状态?
应为HTTP是一种无状态协议。
什么是无状态:请求的时候,BS是连接的,但是请求结束后,连接就断开了。为什么?
因为无状态的协议会降低服务器的压力。
request是请求域。servletContext是应用域
request是一次请求一个对象。
servletContext对象是服务器启动的时候创建的,服务器关闭的时候销毁,这个servletContext对象的域太大
request请求域(HttpSevletRequest)\session会话域(HttpSession),application域(servletContext)
pageContext<request<session<application
他们四个域对象都有以下三个公共的方法:
setAttribute(向域中绑定数据)
getAttribute(向域中获取数据)
removeAttribute(删除域当中的数据)
使用原则:尽量使用小的域
HttpSession session=request.getSession();
从服务器中获取对应的session对象
如果没有获取到任何session对象,则重建。
HttpSession session=request.getSession(false);
从服务器中获取当前的session对象
如果获取不到session,则不会新建,返回一个null
session实现原理
在web服务器当中有一个session列表。类似于map集合。map集合的key存储的是sessionid
这个map集合的value存储的是对应的session对象
用户第一次发送请求的时候:服务器会创建一个session生成一个唯一的id,然后web服务器会将session的id
发送给浏览器,浏览器将session的id保存在浏览器的缓存中。
用户第二次发送请求的时候:会自动将浏览器缓存中的sessionid发送给服务器。服务器获取到sessionid,然后
从session列表中查找到对应的session对象。
为啥关闭浏览器,会话结束?
关闭浏览器之后,浏览器中保存的sessionid消失,下次重新打开浏览器之后,浏览器缓存中没有这个sessionid,自然
找不到服务器中对应的session对象。sessionid是以Cookie的形式保存在浏览器的内存当中的。浏览器只要关闭这个cookie就没有了。
cookiei禁用:
服务器正常发送cookie给浏览器,但浏览器不要了。拒收了。每一次请求都会获取到新的session对象。
cookie禁用了,session还能实现吗?
可以,需要使用url重写机制
url重写机制解决cookie禁用问题。会提高开发者的成本。开发人员在编写任何请求路径的时候,后面都要添加一个sessionid,给开发者带来了
很大的难度,很大的成本。所以大部分的网站都是这样设计的:你要是禁用cookie你就别用了。
session对象找不到等同于会话结束
session两种销毁方式:
①超时销毁
默认值是30分钟
<!--30分钟不访问就消除session对象-->
? ? <session-config>
? ? ? ? <session-timeout>30</session-timeout>
? ? </session-config>
②手动销毁
cookie就是sessionid这个键值对对象
对于浏览器关联的cookie来说,这个cookie是保存在浏览器的运行内存当中的
只要浏览器不关闭,用户再次发送请求的时候,会自动将运行内存当中的cookie发送给服务器。
cookie最终是保存在浏览器客户端上的。
可以保存在运行内存当中。(浏览器只要关闭cookie就消失了)
也可以保存在硬盘文件中。
cookie有啥用?
cookie和session机制其实都是为了保存会话的状态。
cookie是将会话的状态保存在浏览器客户端上
怎末让cookie失效?
十天过后自动失效。
改密码
在客户端浏览器上清除cookie
cookie机制和session机制其实都不属于Java机制,实际上cookie机制和session机制都是HTTP协议中的一部分。PHP开发中也有cookie和session机制,只是如果要作web开发,不管什么编程语言,cookie和session机制都是需要的。
Java程序通过respond.addCookie(cookie);将cookie数据发送给浏览器
当浏览器发送请求时,会自动携带该path下的cookie数据给浏览器(URL)
关于cookie的有效时间
怎末用Java设置cookie的有效时间
cookie.setMaxAge(60*60);设置cookie在一小时后失效
没有设置有效时间:默认保存在浏览器的运行内存中,浏览器关闭则cookie消失。
只要设置cookie的有效时间>0这个cookie一定会保存到硬盘文件中
设置cookie时间=0 ,cookie被删除同名cookie被删除
设置cookie的有效时间<0 保存在运行内存中。和不设置一样。
关于cookie的path,cookie关连的路径:
假设现在发送请求路径是:http://localhost:8080/servlet13/cookie/generate
生成的cookie,如果cookie没有设置path,默认的path是
http://localhost:8080/servlet13/cookie以及他的子路径。
也就是说,只要浏览器的请求路径是http://localhost:8080/servlet13/cookie这个路径以及这个路径下的子路径,cookie都会被发送给到服务器。
手动设置cookie的path
cookie.setPath("/servlet13");表示只要是这个servlet13项目的请求路径,都会提交这个cookie给服务器。
浏览器发送cookie给服务器了,服务器中的Java程序怎样接收?
cookie[] cookies=request.getCookies();//这个方法可能返回null
if(cookies !=null){
for(Cookie cookie:cookies){
? ? //获取cookie的name
? ?String name=cookie.getName();
? ? //获取cookie的value
? ? ? String value=cookie.getValue();
? ? ? ? ? ? ? }
}
---------------------------------------------------------------------------
request.setCharacterEncoding("utf-8");
? ? ? ? response.setContentType("text/html;charset=utf-8");