JavaWeb基础与应用
2.Servlet开发
- Servlet是sun公司提供的一门用于开发动态web资源的技术。
- Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
- 编写一个Java类,实现servlet接口。
- 把开发好的Java类部署到web服务器中。
- 快速入门,用servlet向浏览器输出“hello servlet”。
- 阅读Servlet API,解决两个问题:
- 输出hello servlet的java代码应该写在servlet的哪个方法内?
- 如何向IE浏览器输出数据?
Web的目录结构

Servlet入门基础
方式1:使用配置文件的方式配置servlet
编写一个类继承HttpServlet:重写一个方法service方法
在web.xml配置这个Servlet :配置 <servlet></servlet>、<servlet-mapping></servletmapping>
web.xml中配置:

/**
方式2:使用注解的方式配置servlet
/**
Servlet的运行流程
@WebServlet
Servlet的生命周期
笔面试题:请描述servlet的生命周期
Servlet的生命周期和工作原理
Servlet的的声明周期分为三个阶段:1.初始化阶段 2.响应客户阶段 3.终止阶段
这三个阶段分别对应init方法 service方法 和destory方法,这三个方法分别在不同的阶段进行调用。
1)Servlet的初始化阶段
在以下时刻servlet进行初始化 servlet初始化包含以下三种情况,这三种情况都会执行init方法
a.servlet容器启动后,自动加载某些配置信息。需要配置<load-on-startup></load-on-startup>

b.在servlet容器启动后,客户端第一次向servlet发起请求
c.servlet的文件被更改后 重新加载servlet
注意: init方法只会在第一次初始化servlet的时候执行。
2)servlet响应客户端阶段
Servlet当接受到客户端请求后,servlet会根据这个请求创建两个对象HttpServletRequest对象和HttpServletResponse对象,这个对象分别代表接受请求和响应请求,然后servlet调用service方法。Service方法会根据HttpRequest对象从请求中获取相关的数据,然后处理请求,最后通过HttpResponse对象把数据写出到客户端。
3)servlet终止阶段
- 当web应用被终止,或者servlet容器终止运行
- 或servlet容器被重新加载
- 当前终止的时候回调用destroy方法进行终止。
@WebServlet
Servlet相关的对象
说明:为了美化测试界面,下述测试案例大部分使用BootStrap框架,需要导入相关的css、js、font文件
<1>ServletConfig对象
- 在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
- 当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
- 阅读ServletConfig API,并举例说明该对象的作用:
- 获得字符集编码
- 获得数据库连接信息
- 获得配置文件,查看struts案例的web.xml文件
web.xml配置的参数:可以通过ServletConfig对象获取

/**
<2>ServletContext
- WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
- ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
- 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
- 查看ServletContext API文档,了解ServletContext对象的功能。
案例1:多个servlet共享数据
/**
运行结果:先执行ServletContextDemo1再执行ServletContextDemo2方能获取数据
案例2:获取全局的web初始化参数
web.xml中配置:

/**
案例3:实现servlet之间的转发
/**
结果分析:执行ServletContextDemo4发现页面执行ServletContextDemo5的页面内容,但地址栏不发生变化

案例4:读取资源文件
/**

Request对象和Response对象
- Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
- request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。
<1>HttpServletResponse对象
response细节问题:
- getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
- getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
- Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
- Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
案例1:通过response对象输出中文到客户端
代码分析:
/**
结果展示:
http://localhost:8080/JavaWeb/ResponseDemo1

案例2:通过response对象输完成文件的下载
代码分析:
/**
结果展示:


案例3:通过response对象生成随机图片(验证码)
代码分析:
ResponseDemo3.java:
/**
identify.html:测试页面
<!DOCTYPE html>
结果展示:
http://localhost:8080/JavaWeb/ResponseDemo3

http://localhost:8080/JavaWeb/html/identify.html

<2>HttpServletRequest对象
案例1:通过request对象常用的方法
代码展示:
/**
结果展示:
http://localhost:8080/JavaWeb/RequestDemo1

:
案例2:获取表单的各项输入的数据
代码展示:
RequestDemo2.java:
/**
userRegister.html:用户注册测试界面
<!DOCTYPE html>
userRegister.js:初始化年月日下拉列表
function
结果展示:
http://localhost:8080/JavaWeb/RequestDemo2
如果是直接访问RequestDemo2则没有获取表单提交的数据,显示为null,如果是通过指定的html提交指定的表单数据则正常回显信息
http://localhost:8080/JavaWeb/html/userRegister.html



案例3:通过request请求参数中文乱码问题
代码分析:
RequestDemo3.java
/**
code.html:测试界面
<!DOCTYPE html>
结果显示:
http://localhost:8080/JavaWeb/html/code.html


笔面试题:平时如何解决项目中乱码
1、如果是提交方式是post 如果不想乱码,只需要设置request.setCharacterEncoding("UTF-8"); 和页面的编码集一致 <meta charset="UTF-8">
2、如果提交表单的方式是get,设置request是无效的,如果想获取的参数显示不是乱码,需要重新封装获取的数据再进行输出,参考示例如下:
String username=request.getParameter("username");
username=new String(username.getBytes("ISO-8859-1"),"UTF-8");
System.out.println(username);
3、get方式乱码,还可以通过设置服务器的配置实现,可以在tomcat安装目录下更改conf/server.xml

<3>请求转发和重定向
- 一个web资源接收到客户端请求后,通知浏览器去调用另外一个web资源进行处理,称之为请求转发
- 一个web资源接收到客户端请求后,通知浏览器去访问另外一个web资源,称之请求重定向

代码展示:
/**
结果展示:
a.重定向测试:地址栏发生变化,页面跳转到指定的页面资源
http://localhost:8080/JavaWeb/RequestDemo4
http://localhost:8080/JavaWeb/html/userRegister.html
b.请求转发测试:
地址栏不会发生变化,页面显示指定的页面资源,此处显示css样式失效是由于在指定的html测试文件中的路径设置参考的是当前地址,因此无法准确定位到相应的bootstrap提供的样式,可以明确用${pageContext.request.contextPath}表示当前工程目录即可
http://localhost:8080/JavaWeb/RequestDemo4

笔面试题:请求转发和重定向有什么区别?
- RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。 (范围的不同)
- 如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。 (“/”的含义)
- 调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。(URL地址是否变化)
- HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。 (请求次数和响应次数)
- RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。