经过一段时间的整理,语法篇告一段落,语法篇整理了从JDK一直到多线程的一些面试题,有想看的这里是传送门
JavaEE常见但容易忽略面试题-----语法篇
接下来整理一下WEB篇以及Spring篇的面试题,Spring可能会在下一篇文章,闲言少叙,我们进入正题。
- Servlet的执行流程
目前,最常见的Servlet执行流程如下
浏览器 | 操作 | 服务器 | 操作 | 浏览器 |
---|---|---|---|---|
Chrome | 发起Http请求 | Tomcat | 接收请求,通过url找到对应的Servlet,并将其实例化,执行Service()方法,再返回数据。 | 接收从服务器返回的数据,并将其展示在前台页面中 |
其中需要注意的几点是
一、Servlet并非是在Tomcat启动时实例化,而是在浏览器发送请求到servlet是才被实例化,并且只实例化一次,此后再发请求并不重新实例化。
二、有人就要问了,如果在并发环境下,许多请求同事访问,Servlet如何实例化,其实Servlet是单例多线程模式,只要实例化一次之后,就会以多线程的方式来执行不同的请求。
- Servlet的生命周期
这道题一般是笔试,需要牢记
生命周期一共有五个状态,分别是装载、创建、初始化、提供服务、销毁。
装载:tomcat在启动时会检查web.xml文件,检查其中的servlet
创建:在某个请求访问url时,服务器会根据url找到对应的servlet,并执行其构造方法,对其进行实例化。
初始化:在创建完成后,servlet马上进行初始化,执行init()方法,加载各种资源,初始化是servlet独有的操作,创建是Java层面上的,而初始化是web层面上的。
提供服务:服务器通过用户的请求对其进行服务,执行service()方法,而service()方法又可以根据请求方式的不同来分成doPost()和doGet()方法。
销毁:在服务区被关闭的时候,servlet会执行destory()方法。 - 请求与响应的结构差异
请求一般自上而下分为请求行、请求头、请求体
请求行:一般有请求地址、请求方式、http协议版本
请求头:一般包含一些请求辅助信息,比如请求语言、请求方式等
请求体(Post方式独有)
POST请求时,会将参数以键值对的形式传递给服务器,而GET请求则会将参数拼接在Url地址的后面
响应行:会有响应状态码、以及响应信息等
响应头:同样的,也是一些响应辅助信息,如下图,会显示返回的文件格式是什么,例如text/html就是返回了html的文本,而text/xml则是xml的文本。
响应体:会返回服务器给用户的具体数据。
- 转发与重定向的区别
请求转发
一次请求、请求不变,服务器端跳转
request.getRequestDispatcher().forward()
浏览器发送请求到服务器,服务器使用请求转发到下个页面,相当于浏览器直接发送请求到被转发的页面,所以转发后的URL地址不会变。
响应重定向
二次请求,请求发生变化,浏览器端跳转
response.sendRedirect()
浏览器发送请求到服务器,服务器执行重定向,会先向浏览器发送一个响应,告诉浏览器需要再次发送一个请求到服务器,于是浏览器再次发送请求,此时会发现地址栏中的URL已经发生了变化。 - Session的实现原理
浏览器 | 操作 | 服务器 | 操作 | 浏览器 | 操作 | 服务器 | 操作 |
---|---|---|---|---|---|---|---|
chrome | 发送请求 | tomcat | 返回响应,会生成一个sessionID一并返回 | chrome | 接收请求,并且把收到的sessionID存放在cookie中。再次发送请求 | tomcat | 收到请求后,解析请求中的sessionID,同自己的对比 |
如果SessionID对比相同的话,服务器就会认定发送请求的是同一个人,只要不关闭浏览器,sessionID则会与本地cookie的相同,这样就可以使用get/setAttribute来保存想要留在服务器上的值了。
- JSP九大内置对象
如果要考察JSP的话,九大内置对象必不可少
它们分别是
内置对象 | request | response | session | application | out | page | pageContext | config | exception |
---|---|---|---|---|---|---|---|---|---|
对应Servlet对象 | HttpServletRequest | HttpServletResponse | HttpSession | PrintWriter |
其中application是应用全局对象,代表着整个web容器
page是代表当前页面,类似于this
pageContext用来获取其他八大对象
config用于获取配置文件信息,比如获取web.xml中的初始化参数
exception是异常对象,当前页面可能发生异常的时候,此页面将此异常交给另外一个页面处理。但是使用时,要在page标签内添加 errorPage=“处理异常的页面.jsp”
在异常处理的页面的page处应该添加 isErrorPage=“true”;
- JDBC使用步骤
一、加载JDBC驱动
二、创建数据库连接对象Connection
三、创建命令对象PreparedStatement
四、创建查询对象ResultSet
五、关闭连接
String url = jdbc:mysql://localhost:3306/数据库名?useUnicode=true&charsetEncoding=utf8;
String username = root;
String password = root;//根据自己设置的数据库密码
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url,username,password);
//查询操作
PrepareStatement ps = conn.prepareStatement("insert into student(sname,pwd) values(?,?)");
ps..setString(1,"name");
ps.setString(2,"pwd");
int i = st.executeUpdate();//这里一定要进行更新
if(i > 0){
//插入成功
}
//查询操作
PrepareStatement ps = conn.prepareStatement("select * from student where sname=?");
ps.setString(1,"name");
ResultSet rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getString("sname"));
System.out.println(rs.getString("pwd"));
}
}catch(Exception e){
...
}finally{
conn.close();
ps.close();
if(rs!=null){
rs.close();
}
}
关于JDBC的使用,最好是封装到一个工具类中,并将其写成静态方法,以便使用。
- PrepareStatement和Statement的区别
两者都是连接对象,但是Statement对象是较早的连接对象,它有一个致命的缺陷,就是没有防止SQL注入,SQL注入最经典的危害就是可以绕过登录,直接进入系统,试想一下,这样就相当于自己的系统没有了防火墙,谁都可以进去肆意破坏。
我们都知道,Statement是采用字符串拼接的方式来验证SQL代码,例如我们要验证账号和密码,我们将其中任意一个写成 or 1=1 or,熟悉数据库的小伙伴肯定都知道,这就相当于是一个永真的语句,所以PrepareStatement应运而生,它采用了占位符的机制,可以防止SQL注入的问题,所以在平时应用中,千万要使用PrepareStatement对象。