servlet
servlet生命周期:
init:一般在第一次访问的时候会调用,如果在web.xml中配置了 <load-on-startup>1[启动顺序,1最大]</>的话,服务器启动时调用[Struts]
service: 每次请求都会调用,运行在子线程[同一个servlet,存在线程安全问题,SingleTreadModel(多个)]
destroy: 服务器停止或重新启动调用
web.xml 修改不许重新发布 conf/context.xml 自动检测
servlet 映射: servlet-mapping
/*.* /*.html[伪静态] 通配符 *在前面,优先级最低 *.html最低 < *
/缺省 url找不到,缺省处理 [conf/web.xml defualt]
给次请求都会有新的 request response
servletConfig:加载配置信息
在servlet init中,HttpServlet提供getServletConfig().getInitParameter("key");
<servlet>
<servlet-name>Ss</servlet-name>
<servlet-class>Ss</servlet-class>
<init-param>
<param-name>servletConfigData</param-name>
<param-value>servletConfigValue</param-value>
</init-param>
</servlet>
Struts 加载 struts-config.xml
ServletContext(当前应用,context域,application)
1.servlet数据共享:
全局 setAttribute("",""); getAttribute("","");
2.初始化参数:
getServletContext().getInitParameter("");
web.xml中:
<context-param>
<param-name>x</param-name>
<param-value>xx</param-value>
</context-param>
3.servlet转发:
RequestDispatcher rd = getServletContext().getRequestDispatcher("x.jsp");
rd.forward(request, response);
4.读取资源/配置文件:[类装载(文件不可太大,只装载一次)]
HttpServlet:复写了service方法,自动判断请求方法,实现事件分发,一般
只要实现 doGet/doPost方法
Request[域${xx}]
www.baidu.com 主机名 baidu.com 域名(购买,域下可以以搭建多个网站)
https://xxx.cn/ccc/xx.html url /ccc/xx.html uri
request.getRequestURI();//权限管理
request.getRequestURL();
request.getQueryString();//?name=xx 参数name=xx
request.getRemoteAddr();//ip地址
request.getRemoteHost();//主机名 需要dns注册
request.getRemotePort();//访问端口
request.getLocalAddr();//服务器地址
request.getMethod();//请求方式
1获取请求头 信息
request.getHeader("");
Enumeration<String> e = request.getHeaders("");
while(e.hasMoreElements())//遍历所有的头
{
String value = e.nextElement();
}
2获取数据
request.getParameter("");//
String[] values = request.getParameterValues("");// ?a=1&a=2 同名参数
Map<String, String[]> parameterMap = request.getParameterMap(); // key:values 同名参
request.getCookies();// 获得cookie
3表单和输入项
<form action="/xx/servlet/XxServlet" method="post">
名字<input type="text" name="user_name" /> <br/>
密码<input type="password" name="pwd" /> <br/>
性别<input type="radio" name="sex" />男 <br/>
<input type="radio" name="sex" />女 <br/>
所在地
<select name="location">
<option value="beijing">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
</select> <br/>
爱好
<input type="checkbox" name="habits" />爱好1
<input type="checkbox" name="habits" />爱好2
<input type="checkbox" name="habits" />爱好3
<input type="checkbox" name="habits" />爱好4
<input type="checkbox" name="habits" />爱好5
<br/>
信息<textarea rows="10" cols="50" name="detail"></textarea><br/>
照片 <input type="file" name="headImg"><br/>
<input type="hidden" name="hidden" value="xxxx"><br/>
</form>
<a href="/xx/servlet/xxServlet">点击</a>
4乱码
get提交、超链接
反向查找: xx = new String( xx.getBytes("iso8859-1") , "utf-8"):
post:
在过去参数前: request.setCharacterEncoding("urf-8");
改服务器配置(tomcat):
conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" UEIEncoding="utf-8" />
或
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" useBodyEncodingForURI="true" />
+ request.setCharacterEncoding("urf-8");
5转发
1.客户端只发送一次请求,服务器多个资源调用
2.客户端地址没有变化
request.getParameter("key"); //客户端提交的数据
request.setAttribute("key", "value");//服务器自行存储的数据
request.getAttribute("key");
/**
* 1.forward 之前 如果outputStream/writer.close(); 报状态异常
* 2.out.write("".getBytes());然后forward,写的数据将被清空
*/
request.getRequestDispatcher("/WEB-INF/jsp/xx.jsp").forward(request, response);
6包含
//公共部分 不要包含全局html标签
request.getRequestDispatcher("/publi/head.jsp").include(request, response);
response.getWriter().write("xxx");
request.getRequestDispatcher("/publi/foot.jsp").include(request, response);
7防盗链
String header = request.getHeader("referer");
if(header == null || !header.startsWith("http://主机名"))
{
response.sendRedirect("/xxProject/index.jsp");//代表:网站 + web应用
}
7项目目录
request.getContextPath();
8封装bean
public static <T> T toBean(Request request, Class<T> clazz) {
try {
T bean = clazz.newInstance();
ConvertUtils.register(new DateConverter(), java.util.Date.class);
BeanUtils.populate(bean, request.getParameterMap());
return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Response
响应头:
写数据:字节、字符不能同时调用
response.setCharacterEncoding("utf-8"); //设置response码表
response.setHead("Content-type","text/html;charset=utf-8");
== out.write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes())
== response.setContentType("text/html;charset=utf-8");[+设置response码表 ]
字节:OutputStream
response.getOutputStream().write(“”.getBytes("utf-8"))
中国(utf)编码 涓浗( gbk )打开
字符:PrintWrite写字符/字符串 多个换行
response.getWriter().write("");
addCookie(cookie); // 写cookie
定时刷新
response.setHead("refresh","3;url='xxx.cn' ");
==out.write("<meta http-equiv='refresh' content='3;url=xxxx.cn'>".getBytes())
缓存
response.setHead("expries",3;1000*60);//1分钟
下载
response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode("美女.jpg"));
状态码
请求重定向
response.setStatus(302); response.setHeader("location","/xx/x.html");
==response.sendRedirect("xx/xx.jsp");
Filter接口
1.指定编码,必须在 链中 第一次调用writer之前!!!
2.doFilter, 执行下一个优先级高的filter 直到最后才放行,,,链 ,,,,,多个匹配,按照web.xml中filter-mapping的顺序
3.一个ffilter可以配置多个mapping
web.xml
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>junit.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/xx.html</url-pattern> <!--资源 -->
<servlet-name>xxServlet</servlet-name><!--名称 -->
<dispatcher>REQUEST</dispatcher><!-- 类别FORWARD INCLUDE REQUEST ERROR -->
<dispatcher>ERROR</dispatcher>
</filter-mapping>
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
//指定编码,必须在 链中 第一次调用writer之前!!!
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("before");
// 链条 执行下一个优先级高的filter 直到最后才放行
chain.doFilter(request, response);//2
response.getWriter().write("after");
//拦击作用
}
public void init(FilterConfig filterConfig) throws ServletException
{
//服务器启动加载、服务器关闭摧毁,,和servlet益阳枯叶配置初始化参数
}
public void destroy()
{
}
/ 拦截请求,不拦截静态资源
/* 拦截所有
Listener接口
分类
监听三个对象的创建和销毁
ServletContextListener
创建:服务器启动的时候,会为每一个项目都创建一个servletContext
销毁:服务器关闭的时候,或者项目被移除的时候
以后用来加载配置文件,整个项目初始化工作
ServletRequestListener
创建:请求来的时候
销毁:响应生成的时候
统计ip、统计页面的访问次数
HttpSessionListener
创建:
java中第一次调用request.getSession的时候
jsp访问的时候创建
销毁:
三种情况:
session超时
手动销毁session
服务器非正常关闭
统计并发人数(session误差)、统一管理session,优化内存
监听三个对象属性的变化(添加 替换 删除)
ServletContextAttributeListener
ServletRequestAttributeListener
HttpSessionAttributeListener
监听session中javabean的状态
注意:这两个接口需要javabean实现.是让javabean感知到自己的状态
HttpSessionBindingListener(绑定和解绑),javabean实现接口(不需要注册)统计在线用户
检测java是否添加到session或者从session中移除
HttpSessionActivationListener(钝化和活化)
钝化:javabean从session中序列化到磁盘上
活化:javabean从磁盘上加载到了session中
2.服务器启动,监听器自动实例化(listener比filter先实例化)
3.web.xml注册:
<listener>
<listener-class>com.xxx.aaListener</listener-class>
</listener>