1. 基础问题
servlet生命周期:
tomcat等容器将请求分解成 HttpServletRequest/HttpServletResponse --> 调用servlet.init()
-->servlet.service() 调用doGet/doPost处理 --> servlet.destroy() 一般只需重写doGet/doPost即可
web.xml 的加载顺序:
context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用顺序是根据对应的 mapping 的顺序进行调用的。
Web应用的初始化
代码:ContextConfig.configStart(),一个应用对应一个Context容器
-->先加载$Tomcat/conf/web.xml,再加载用下的 examples/WEB-INF/web.xml
-->将webXML中解析出的属相(包括filter/listener)等设置到Contex容器中
-->紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文.
-->容器将<context-param></context-param>转化为键值对,并交给ServletContext.
-->容器创建<listener></listener>中的类实例,即创建监听.
-->获得ServletContext =ServletContextEvent.getServletContext();
2. Web.xml常用元素
<web-app>
<display-name>定义WEB应用的名字</display-name>
<icon> //web应用的大/小图标
<small-icon>/images/app_small.gif</small-icon>
<large-icon>/images/app_large.gif</large-icon>
</icon>
<context-param> //context-param元素声明应用范围内的初始化参数,ServletContextEvent.getServletContext().getInitParameter("context/param")
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<filter> //过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联;
<filter-name>setCharacterEncoding</filter-name>
<filter-class>com.myTest.setCharacterEncodingFilter</filter-class>
<init-param> //用来设置初始化参数,可以从filterConfig对象中获取
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
</filter>
<filter-mapping> //利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联
<filter-name>setCharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener> //选择监听servlet生命周期中的每种事件,继承EventListener接口
<listener-class>com.myTest.ContextListener</listener-class>
</listener>
<servlet> //配合servlet-mapping,指定URL的映射类
<servlet-name>ShoppingServlet</servlet-name>
<servlet-class>com.myTest.ShoppingServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
</init-param>
<load-on-startup>1</load-on-startup> //
</servlet>
<servlet-mapping>
<servlet-name>ShoppingServlet</servlet-name>
<url-pattern>/shop/ShoppingServlet</url-pattern>
</servlet-mapping>
<session-config> //session超时事件,如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存
<session-timeout>120</session-timeout>
</session-config> 。
<welcome-file-list> //指定首页名称
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcom-file-list>
<error-page> //指定用来处理特定错误代码或异常的页面
<error-code>404</error-code>
<location>/error404.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/exception.jsp</location>
</error-page>
</web-app>
3. 配置Spring
<!-- 指定spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
<!--加载多个spring配置文件 -->
/WEB-INF/applicationContext.xml, /WEB-INF/action-servlet.xml
</param-value>
</context-param>
<!-- 定义SPRING监听器,加载spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener
4. Filter
1) 对被访问的URL进行预处理,如记录日志、验证等公共逻辑
2) 过滤器链:若存在多个匹配给定URL模式的个过滤器,它们就会根据web.xml里的配置顺序被调用。
3) 包含相同URL模式的过滤器(filter)会在Servlet调用前被调用
4) 过滤器需实现javax.servlet.Filter, init()/destroy()被容器调用。 doFilter()实现处理逻辑,
调用chain.doFilter(request, response)往下执行
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
{
System.out.println(request.getProtocol());
chain.doFilter(request, response);
}
4. Filter示例1
- 必须继承HttpServlet,要么继承GenericServlet的普通Servle, 要么HttpServlet 的HTTP Servlet。
- 重写doGet() 和 doPost() 方法,如果你向这个servlet发送一个HTTP GET请求,doGet()方法就会被调用。其它方法一般不需重写。
- 获取参数: String value1 = req.getParameter("param1");
- 为了发送内容给客户端,从HttpServletResponse获取PrintWriter,任何写到这个对象的内容都会被写进outputstream里发到client。
public class FirstServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try
{
// Write some content
out.println("<html>");
out.println("<head>");
out.println("<title>MyFirstServlet</title>");
}
}
5. Servlet
5.1 < load-on-startup >标签-启动时执行java类
1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2)它的值必须是一个整数,表示servlet应该被载入的顺序
2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
5)当值相同时,容器就会自己选择顺序来加载。
5.1 Servlet下载文件
Servlet提供一个相应类型(Content-Disposition),并将文件流写入输出流
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
final int BYTES = 1024;
int length = 0;
ServletOutputStream outStream = response.getOutputStream();
ServletContext context = getServletConfig().getServletContext();
response.setContentType("text/plain");
String fileToDownload = "resources/files/dtfile.xds";
response.setHeader("Content-Disposition", "attachment; filename=" + fileToDownload.split("/")[2]);
InputStream in = context.getResourceAsStream("/" + fileToDownload);
byte[] bbuf = new byte[BYTES];
while ((in != null) && ((length = in.read(bbuf)) != -1))
{
outStream.write(bbuf, 0, length);
}
outStream.flush();
outStream.close();
}
6. 上传文件
A).页面,index.html
<input id="upload" type="button" value="上传" />
<script>
$("#upload").click(function(){
debugger;
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
url : '/servletexample/upload',
type : 'POST',
cache : false,
data : formData,
processData : false,
contentType : false
}).done(function(res) {
alert("上传成功");
}).fail(function(res) {
});
});
</script>
b).后台java
Part表示一个上传文件,part.write()会将上传的文件写入到临时目录apache-tomcat-8.0.36workCatalinalocalhostservletexample
//上传的文件需要自己复制保存到指定位置,临时文件会被清空
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Collection<Part> parts = request.getParts();
System.out.println("parts num:" + parts.size());
Iterator<Part> temp = parts.iterator();
while (temp.hasNext())
{
Part part = temp.next();
System.out.println(part.getSubmittedFileName());
part.write(part.getSubmittedFileName());
}
}
c).web.xml , multipart-config必须配置在上传的servlet中
<servlet>
<servlet-name>uploadfileServlet</servlet-name>
<servlet-class>com.servlet.test.UploadFileServlet</servlet-class>
<!-- 文件上传的配置 -->
<multipart-config>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>uploadfileServlet</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>