“人生如一杯茶,不会苦一辈子,但要苦一阵子。”
你好,我是梦阳辰!和我一起学习起来吧!
Servlet进阶教程(你不得不知道的Servlet知识点)
Java EE实质上是sun(oracle)公司为我们提供的强大的类库。
Java SE实质就是sun(oracle)公司提供的一套基础的类库。
Java EE是 J2EE的一个新的名称,之所以改名,目的还是让大家清楚J2EE只是Java企业应用.随着WEB和EJB容器概念诞生,使得软件应用业开始担心SUN的伙伴们是否还在Java平台上不断推出翻新的标准框架,致使软件应用业的业务核心组件架构无所适从,从一直以来是否需要EJB的讨论声中说明了这种彷徨。
在2004年底中国软件技术大会Ioc微容器(也就是Jdon框架的实现原理)演讲中指出:我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本.此次J2EE改名为Java EE,实际也反映出业界这种共同心声。
Java EE的核心是EJB3.0, 其提供了更兼便捷的企业级的应用框架。
1.什么是JavaSE?
Java的标准版本
sun公司为java程序员提供的一套基础类库。这套基础类库包括基础语法、面向对象、异常、IO、集合、反射、线程
目前JavaSE由Oracle公司维护。
2.什么是API?包括什么?
应用程序接口
API包括:源码、字节码、帮助文档
3.JavaSE的src、字节码、帮助文档在哪里?
JAVA_HOME\src.zip
JRE_HOME\lib\rt.jar
帮助文档,官网。
4.什么是JavaEE?
Java企业版
SUN公司为Java程序员准备另一套庞大的类库,帮助程序员完成企业级项目开发。
JavaEE规范是一个比较大的规范,JavaEE包括13个子规范(每一个子规范下其实还有其他的子规范)
JavaEE5规范下的子规范:
Servlet2.5
JDBC
JavaEE6规范下的子规范。
Servlet3.0
Tomcat服务器,其中Tomcat6实现了Servlet2.5规范,Tomcat实现了Servlet3.0规范。
5.JavaEE的源码、字节码、帮助文档在哪里?
系统架构分类
C/S
B/S
什么是C/S呢?
各种app。
优点:大部分数据都以集成到客户端软件中,只需要从服务器上传送少量数据即可。速度快。
升级麻烦。
什么是B/S呢?
客户端为浏览器。不需要安装特定的客户端。升级方便。
缺点:速度慢,体验差。
以后主要的研究方向。
BS架构访问过程
注意:Servlet接口由程序员实现,服务器来调用。
Servlet:是两个英语单词的合并,Serv表示服务器端,let表示小程序。
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
知识引入:
1.Sun公司制定的JavaEE规范:Servlet规范
Servlet接口是Servlet规范中核心接口
接口注意:调用这是谁?实现者是谁?
public interface Servlet{//Servlet接口
void service();
}
2.JavaWeb程序员
JavaWeb编写服务器端小java程序的时候,不能随意编写,必须实现Servlet接口。
public class DeleteServlet implements Servlet{
public void service(){
System.out.println("连接数据库,成功...");
}
}
3.Tomcat服务器调用(自动调用)
WebServer Web服务器 ,Web Container
Web容器面向Servlet接口调用。
作为Web程序员我们只要实现Servlet接口,并配置号.xml文件即可。
1.一个webapp只有一个web.xml文件。
web.xml文件主要配置请求路径和Servlet类名之间的绑定关系。
web.xml文件在Tomcat服务器启动阶段被解析。解析失败会导致webapp启动失败。web.xml文件中的标签不能随意编写。
在项目目录下必须有一个WEB-INF文件夹。并且在WEB-INF文件夹下必须有classes文件夹,lib文件夹和web.xml配置文件。
.class文件放在classes文件夹下。
实例:
编写Java程序,将编译生成的class文件放在classes目录下。
配置web.xml
注意对于xml配置文件的<url-pattern>中的路径不需要添加项目名。
但是对于Hello.html的文件的超链接需要在前面添加项目名,因为超链接可能
会转到其他项目中,也可能转到其他网站,所以需要在其前面添加项目名称。
java代码:(其它类似)
package Part1;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MengYangChenWorkers implements Servlet {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out=response.getWriter();
out.print("");
out.print("");
out.print("员工信息 ");
out.print("");
out.print("");
out.print("员工列表
");
out.print("
");
out.print("");
out.print("");
out.print("编号 ");
out.print("姓名 ");
out.print("性别 ");
out.print("部门 ");
out.print("生日 ");
out.print(" ");
//JDBC
Connection conn=null;
PreparedStatement ps =null;
ResultSet rs= null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/newdata","root","0910");
String sql="select num,name,sex,classnum,birthday from t_student";
ps=conn.prepareStatement(sql);
rs=ps.executeQuery();
while(rs.next()) {
String num=rs.getString("num");
String name=rs.getString("name");
String sex=rs.getString("sex");
String classnum=rs.getString("classnum");
String birthday=rs.getString("birthday");
out.print("");
out.print(""+num+" ");
out.print(""+name+" ");
out.print(""+sex+" ");
out.print(""+classnum+" ");
out.print(""+birthday+" ");
out.print(" ");
}
}catch(Exception e) {
e.printStackTrace();
}finally {
if(rs!=null)
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(ps!=null)
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(conn!=null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
out.print("
");
out.print("");
out.print("");
}
}
在eclipse中Ctrl+ shift +O可以快速导包。Ctrl+O提示类中所有的方法,用于快速查找。
1.什么是生命周期
表示一个java对象从最初被创建到最终被销毁,经历的所有过程。
2.Servlet对象的生命周期是谁来管理的?程序员可以干涉吗?
Servlet对象的生命周期,javaweb程序员是无权干涉的,包括该Servlet对象的相关方法的调用,javaweb程序员也是无权干涉的。Servlet对象从最初的创建,方法的调用,以及对象的销毁,整个过程,是由WEB容器来管理的。
WEB Container管理Servlet对象的生命周期。
3.若希望在web服务器启动阶段实例话Servlet的对象需要进行特殊的设置。
4.从执行结果看:单实例多线程执行。多线程共享一个对象。
所有过程都是由web容器完成的,我们只需要编写方法。
5.描述Servlet的生命周期。(重点)
1.用户在浏览器地址栏上输入url:http://localhost/ServletTimes/TestLifeCycle
2.web容器截取请求路径/ServletTimes/TestLifeCycle
3.web容器在容器上下文中找请求路径/ServletTimes/TestLifeCycle对应的Servlet对象。
4.若没有找到对应的Servlet对象。
4.1.通过web.xml文件中相关的配置信息,得到请求路径/TestLifeCycle对应得Servlet完整类名。
4.2.通过反射机制,调用Servlet类的无参数构造方法完成Servlet对象的实例化。
4.3.web容器调用Servlet对象的init方法完成初始化操作。
4.4.web容器调用Servlet对象的service方法提供服务。
5.若找到对应的Servlet对象。
6.web容器关闭的时候/webapp重新部署的时候/该Servlet对象长时间没有用户再次访问的时候,web容器会将该Servlet对象销毁,在销毁对象前,web容器会调用Servler对象的destroy方法,完成销毁之前的准备。
总结:
Servlet类的构造方法只执行一次。
Servlet对象的init方法只执行一次。
Servlet对象的service方法,只要用户请求一次,则执行一次。
Servlet对象的destroy方法只执行一次。
注意:init方法执行的时候,Servlet对象已经被创建好了。destroy方法执行的时候Servler对象还没有被销毁,即将被销毁。
Servlet对象是单实例,但是不符合单例模式,只能称为伪单例,真单例的构造方法是私有化的,Tomcat服务器是至此多线程的。所以Servler对象在单实例多线程的环境下运行的。如果Servlet对象中有实例变量,并且实例变量涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题,不建议在Servlet对象中使用实例变量,尽量使用局部变量。
6.如果希望在web服务器启动阶段实例化Servlet对象,需要在web.xml文件中进行相关的配置。
<servlet>
<servlet-name>TestLifeCycle</servlet-name>
<servlet-class>Part1.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>//这个为添加项
</servlet>
load-on-startup中1的含义:表示优先级,当有多个类时,将按照这里的优先级,创建对象。自然数越小优先级越高。
例如:当有两个类时。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>Welcome.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TestLifeCycle</servlet-name>
<servlet-class>Part1.HelloServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TestLifeCycle</servlet-name>
<url-pattern>/Test</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Cycle</servlet-name>
<servlet-class>Part1.WelcomeServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Cycle</servlet-name>
<url-pattern>/Tef</url-pattern>
</servlet-mapping>
</web-app>
7.Servlet对象实例化之后,这个Servlet对象被存储到哪里?
大多数WEB容器都是将该Servlet对象以及对应的url-pattern存储到Map集合中了。
在WEB容器中有这样一个Map集合。
Map
key value
---------------------------
/login LoginServlet对象引用
/delete DeleteServlet对象引用
/save SaveServlet对象引用
8.服务器在启动的时候就会解析webapp的web.xml文件,做了什么?
将web.xml文件中的url-pattern和对应的Servlet完整类名存储到Map集合中。
在WEB集合中有这样一个Map集合(没找到的时候)
Map
key value
----------------
/login Part1.LoginServlet
/delete Part1.DeleteServlet
9.Servlet接口中的这些方法中编写什么代码?什么时候使用这些方法。
9.1 无参构造方法【不考虑构造方法】
9.2 init方法
以上两个方法执行事件几乎相同,执行次数都是1,构造方法执行的时候对象正在创建,init方法执行的时候对象已经创建。
若系统要求在对象创建时刻执行一段特殊的程序,这段程序尽量写到init方法中。
9.3 service方法。
这个方法是必然要重写的,因为这个方法需要完成业务逻辑的处理,请求的处理,以及完成响应。
9.4 destrory方法。
这个方法也是SUN公司为javaweb程序员提供的一个特殊的时刻,这个特殊的时刻被称为对象销毁时刻。若希望在销毁时可执行一段特殊的代码,需要将这段代码编写到destroy方法,自动被容器调用。
回顾:
类加载时刻执行程序,代码写到哪里?
编写到静态代码块中。
结论:sun公司为我们程序员提供了很多个不同的时刻。若在这个特殊时刻执行特殊的程序,这些程序是有位置编写的。
1.什么是UML?
统一建模语言(Unified Modeling Language,UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具,独立于任何具体程序设计语言。
UML是一个独立的学科。
UML属于软件工程学
2.UML建模工具?
StarUML
Rational Rose…
3.UML图有哪些?
类图:描述类的信息以及类与类之间的关系。
时序图:描述一个程序的执行过程。
状态图:描述一个对象的生命周期。
用例图:站在系统用户的角度分析系统中存在哪些功能。
1.Apache Tomcat服务器实现了Servlet规范,Tomcat服务器专门写了一个ServletConfig接口的实现类。
实现类的完整类名是:org.apache.catalina.core.StandardWrapperFacade【了解即可】
2.javaweb程序员在编写的时候,一直是面向ServletConfig接口去完成调用,不需要关心具体的实现类。
webapp放到Tomcat服务器中,ServletConfig的实现类是:org.apache.catalina.core.StandardWrapperFacade
webapp放到另一个服务器中(如JBOSS):ServletConfig的实现类可能是另外一个类名了。
3.Tomcat服务器是一个实现了Servlet规范和JSP规范的容器。
4.ServletConfig接口有哪些常用的方法。
//1.通过初始化参数的name获取
String getInitParameter(String name)
//2.获取所有初始化参数的name
Enumeration<String> getInitParameterNames()
//3.获取ServletContext【Servlet上下文】对象
ServletContext getServletContext()
//4.获取servletname
String getServletName()
对应的代码实现:
package Part1;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServletConfigA implements Servlet {
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
//将局部变量赋值给实例变量,使得其他方法中也可以使用config
this.config=config;
System.out.println("AServlet's ServletConfig="+config.toString());
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取ServletConfig
ServletConfig config=getServletConfig();
//1.通过初始化参数的name获取value
/*
* String driver=config.getInitParameter("driver"); String
* url=config.getInitParameter("url"); String
* user=config.getInitParameter("user"); String
* passcode=config.getInitParameter("passcode");
*/
//2.获取所有初始化参数的name
/*
* Enumeration names=config.getInitParameterNames();
* while(names.hasMoreElements()) {
* String name=names.nextElement();
* String value=config.getInitParameter(name);
* out.print(name+"="+value);
* out.print("
"); }
*/
//3.获取ServletContext【Servlet上下文】对象
ServletContext application =config.getServletContext();
out.print(application.toString());
//4.获取servlet Name
/*
* String servletName=config.getServletName();
* out.print(""+servletName+" ");
*/
/*
* out.print(driver); out.print("
"); out.print(url); out.print("
");
* out.print(user); out.print("
"); out.print(passcode);
*/
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
//这个方法供子类使用,在子类中若想获取ServletConfig,可以调用这个方法
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return config;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}
5.ServletConfig到底是什么?
ServletConfig是一个Servlet对象的配置信息对象,ServletConfig对象中封装了一个Servlet对象的配置信息。
Servlet对象的配置信息在web.xml文件中。
一个Servlet对象对应一个ServletConfig对象,100个Servlet对象对应100个ServletConfig对象。
7.将init方法中的ServletConfig参数移动到service方法中,因为我们程序员主要编写的方法是service方法,在service方法中我们可能需要使用Sevletconfig接口。
7.1在init方法中完成:局部变量config赋值给实例变量config
7.2实现getServletConfig方法,提供公开的get方法目的是供子类使用。
1.javax.servlet.ServletContext接口,Servlet规范。
2.Tomcat服务器对ServletContext接口的实现类的完整类名:org.apache.catalina.core.ApplicationContextFacade
javaweb程序员还是只需要面向ServletContext接口调用方法即可,不需要关心Tomcata具体的实现。
3.ServletContext到底是什么?什么时候被创建?什么时候被销毁?创建几个?
ServletContext被翻译为:Servlet上下文【Context一般翻译为上下文】
一个webapp只有一个ServletContext对象
一个webapp只有一个web.xml文件,web.xml文件服务器启动阶段被解析。
ServletContext在服务器启动阶段被实例化。
ServletContex在服务器关闭的时候会被销毁。
ServletContext对应的是web.xml文件,是web.xml文件的代表。
ServletContext是所有Servlet对象四周环境的代表。【在同一个webapp中,所有的Servlet对象共享一个四周环境对象,该对象就是Servletcontext】
所有的用户若想共享同一个数据,可以将这个数据放到ServletContext对象中。
一般放到ServletContext对象中的数据是不建议修改操作的。因为ServletContext是多线程共享的一个对象,修改的时候会存在线程安全问题。
4.ServletContext接口中有哪些常用方法?
//从ServletContext范围中获取数据(Object value=map.get(key);)
Object getAttribute(String name)
//移除ServletContext范围的数据(map.remove(key);)
void removeAttribute(String name)
//向ServletContext范围中添加数据value(map.put(key,value))
void setAttribute(String name,Object object)
String getInitParameter(String name)
Enumeration getInitParameterNames()
String gerRealPath(String path)
实例:
package Part1;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServletConfigB implements Servlet {
private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
//将局部变量赋值给实例变量,使得其他方法中也可以使用config
this.config=config;
//System.out.println("BServlet's ServletConfig="+config.toString());
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
PrintWriter out =response.getWriter();
//获取ServletConfig
ServletConfig config=getServletConfig();
//获取ServletContext【Servlet上下文】对象
ServletContext application =config.getServletContext();
//System.out.println("HelloServletConfigB's ServletContext="+application);
//out.print("HelloServletConfigB's ServletContext="+application);
//获取上下文初始化参数的name(ServletContext方法)
Enumeration<String>names =application.getInitParameterNames();
while(names.hasMoreElements()) {
String name=names.nextElement();
//通过上下文初始化参数的name获取value
String value=application.getInitParameter(name);
out.print(name+"="+value);
}
//获取文件的绝对路径
String realPath=application.getRealPath("/index.html");
out.print(realPath);
//创建User对象
User user=new User();
user.setPasscode("1234");
user.setUsername("Meng");
//向ServletContext范围中存储数据
application.setAttribute("UserObj",user);
application.removeAttribute("UserObj");
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
//这个方法供子类使用,在子类中若想获取ServletConfig,可以调用这个方法
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return config;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
}
5.Servlet,ServletConfig,ServletContext之间的关系。
一个Servlet对应一个ServletConfig,100个Servlet对应100个ServletConfig
所有的Servlet共享一个ServletContext对象。
6.ServletContext范围可以完成快用户传递数据。
总结:
所有编写过的路径:
1.超链接
<a href="/webappname/xxx"></a>
2.web.xml中的url-pattern
<url-pattern></url-pattern>
3.form表单的action属性
<form action="/webappname/xxx"></form>
4.application.getRealPath(path);
1.欢迎页面怎么设置?
假设在WebContent目录下创建index.html,想让index.html作为整个webapp的欢迎也页面。应该做这样的设置。
在web.xml文件的开始
<welcome-file-list>
<welcome-file>Welcome.html</welcome-file>
</welcome-file-list>
设置欢迎页面的目的
为了访问更方便,为了提高用户的体验。
2.欢迎页面可以设置多个
如果上一个资源找不到或者不存在,会往下查找。越往上优先级越高。
3.欢迎页面设置的时候,路径不需要以“/”开始。
<welcome-file>index.html</welcome-file>
要求在webapp的根目录下,必须有一个文件,叫做index.html
<welcome-file>html/welcome.html</welcome-file>
要求在webapp的根目录下,必须有一个文件夹html,该文件夹必须有一个文件叫做welcome.html
4.一个webapp的欢迎页面不一定是一个HTML资源,可以是任何一种类型的web资源,欢迎页面可以是Servlet.
5.欢迎页面包括全局配置和局部配置。
全局配置:catalina_home/conf/web.xml
局部配置 :CATALINA_HOME/webapps/webapp/WEB-INF/web.xml
注意:就近原则
若一个页面的名称是:index.html,index.htm,index.jsp,这些都是默认的欢迎页面,在全局配置中配置过了。
在webapp中常见的错误代码:
404 Not Found【资源未找到:请求的资源路径写错了】
500 Server Inner Error【服务器内部错误,这种情况一般都是java程序出现异常】
404和500是HTTP协议状态码。
以上的这些状态号是W3C制定的,所有浏览器和服务器都必须遵守。
正常响应的HTTP协议状态码:200【ok】。
可以设置错误提示页面(让交互性更好):
在web.xml中编辑:
<error-page>
<error-code>404</error-code>
<location>/error/error.html<location>
<error-page>
<error-page>
<error-code>404</error-code>
<location>/error/error.html<location>
<error-page>
路径总结:
第一类:以/开始,加webapp名称。
第二类:以/开始,不加webapp名称。
除以上两类之外,欢迎页面设置比较特殊,不以/开始,不加webapp的名字。
成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。你好,我是梦阳辰!期待下次的相遇!
关注公众号【轻松玩编程】回复关键字“电子书”,“计算机资源”,“Java从入门到进阶”,”JavaScript教程“,“算法”,“Python学习资源”,“人工智能”等即可获取学习资源。