目录
1.Servlet生命周期
Servlet的生命周期:从Servlet被创建到Servlet被销毁的过程
一次创建,到处服务
一个Servlet只会有一个对象,服务所有的请求
* 1.实例化(使用构造方法创建对象)
* 2.初始化 执行init方法
* 3.服务 执行service方法
* 4.销毁 执行destroy方法
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
public HelloServlet() {
System.out.println("HelloServlet");
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("init");
}
/**
* 当Servlet参数配置时要重写
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("init(ServletConfig config)");
}
/**
* 分发请求,如果是post则调用dopost 如果是get 则调用doget方法
* 一般不重写
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("service"+Thread.currentThread().getName());
super.service(req, resp);
}
/**
*
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
System.out.println("doGet");
}
/**
* 当servlet销毁时调用
* 一般不用重写
*/
@Override
public void destroy() {
super.destroy();
System.out.println("destroy");
}
}
2.乱码问题
1.提交表单乱码
a).request.setCharacterEncoding("utf-8");
b).String username=request.getParameter("username");
String x=new String(username.getBytes("iso-8859-1"), "utf-8");
2.响应编码
a).设置流的编码
response.setCharacterEncoding("utf-8");
b).设置浏览器解析编码
response.setContentType("text/html;charset=utf-8");
3.静态文件乱码
<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">
3.ServletConfig
1.得到servletConfig
a) @Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
b) this.getServletConfig();
2.取出servletConfig里面的值
a) 取单个值 config.getInitParameter("encoding");
b) 去所有值
Enumeration<String> strs=config.getInitParameterNames();
while(strs.hasMoreElements()){
String key=strs.nextElement();
System.out.println(key+":"+config.getInitParameter(key));
}
4.ServletContext (Servlet上下文)
1.配置方式 web.xml----web-app根目录里面
<context-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</context-param>
<context-param>
<param-name>name</param-name>
<param-value>张三</param-value>
</context-param>
2.取值
// 取全局的上下文信息
ServletContext context = request.getServletContext();
ServletContext context2 = this.getServletContext();
Enumeration<String> strs = context.getInitParameterNames();
while (strs.hasMoreElements()) {
String key = strs.nextElement();
System.out.println(key + ":" + context.getInitParameter(key));
}
5.Cookie
特点:
- 由servlet创建 并发送给浏览器
- 保存浏览器里面【可能是硬盘】
- 可以以秒为单位设置cookie的时间
- 如果设置有时间cookie就存放硬盘里面
- 如果没有设置时间cookie就在浏览器的内存时面{关了就没有了}
设置cookie的方法
Cookie cookie1=new Cookie("name", "tom");//创建cookie
cookie1.setMaxAge(10);//只能活10秒 设置存活时间
把cookie发送到浏览器:response.addCookie(cookie1)
Cookie[] kies=request.getCookies();
for (Cookie cookie : kies) {
System.out.println(cookie.getName()+":"+cookie.getValue()+"--"+cookie.getMaxAge());
}
6.Session
1.session创建
a). 当请求jsp或者servlet时就会生成jsessionid 这个id是服务器容器里面的session对象的id 如果jsp页面不相用session 那么可以加入session="false" 也可以通过servlet 里面的request.getSession(false)来禁用seesion
b). Session如果没有被禁用的话,是服务器帮忙创建,它一个对象 一个会话对应一个session 对于选项卡的浏览器一般只是浏览器不关,就只会生成一个jsessionid 如果不是,那就会多个jsessionid
c). html.htm 是没有session
2.session消失【1,超时 2,注销】
a). 默认的session是存在30分钟
b). 可以在web.xml里面设置
<session-config>
<session-timeout>10</session-timeout>
</session-config>
c). 在java代码里面设置 【基本不用】
httpSession.setMaxInactiveInterval(10);
d). 直接清除session [也就是登陆中的注销功能]
httpSession.invalidate();
3.session存在于服务器里面 tomcat容器里面
4.session是一个容器,可以存放会话过程中的任何对象
session.setAttribute(key,obj);
7.Servlet的三大作用域
- httpServletRequest ----jsp request
|---setAttribute(key ,obj);
作用域 请求----到响应 结束之后属性值就消失了
2. HttpSession ----jsp session
|-- setAttribute(key ,obj);
作用域 是一个会话jsessionid 只要jsessionid存在,并且在服务器没有超时或注销,就 会一直存在
3. ServletContext ----jsp application
|-- setAttribute(key ,obj);
随着服务器的关闭而消失 ,当服务器启动时就产生了
8.过滤器
一般在Servlet里面会有三个过滤器
a. 日志过滤器
记录用户访问了哪些资源 ,并转到哪些资源里面
b. 编码过滤器
处理用户请求的一些编码设置,从而不用去每个Servlet里面去设置
c. 未登陆过滤器
如果用户没有登陆,提示用户登陆,不走Servlet,而直接跳到用户登陆页面
1.自定义一个日志过滤器 LogFilter
public class LogFilter implements Filter {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 构造方法
* 当启动服务器里执行
* 只会执行一次
*/
public LogFilter() {
System.out.println("过滤器已加载" + sdf.format(new Date()));
}
/**
* 当服务器启时执行
* 执行一次
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器已初始化" + sdf.format(new Date()));
}
/**
* 当过滤销毁时执行
*/
@Override
public void destroy() {
System.out.println("过滤器已销毁" + sdf.format(new Date()));
}
/**
* 过滤相关请求
* request===HttpServletRequest
* response===HttpServletResponse
* chain 是否放行
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// System.out.println("request:" + request);
// System.out.println("response:" + response);
System.out.println("有用户访问,地址为:"+request.getRemoteAddr()+" 端口为:"+request.getRemotePort()+" 时间:"+sdf.format(new Date()));
System.out.println("doFilter" + sdf.format(new Date()));
chain.doFilter(request, response);
System.out.println("用户访问结束,时间:"+sdf.format(new Date()));
}
}
web.xml配置
<!-- 配置过滤器 -->
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter包名</filter-class>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<!-- /*代表过滤所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2.编码过滤器 EncodingFilter
public class EncodingFilter implements Filter {
private String encoding;
private String contentType;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
response.setContentType(contentType);
//放行
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
encoding=filterConfig.getInitParameter("encoding");
System.out.println("--------------------------"+encoding);
contentType="text/html;charset"+encoding;
}
}
web.xml配置
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>EncodingFilter包名</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.未登陆拦截 LoginFilter
public class LoginFilter implements Filter {
private String redirectPage;
private String loginStr;//login.jsp.login.action
private String [] loginStrs;
private String includeStr;
private String [] includeStrs;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// session里面肯定有user对象
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
User user = (User) req.getSession().getAttribute("user");
if (user != null) {// 如果用户不为空那么,说明用户已经成功登陆
chain.doFilter(request, response);
} else {
// 如果用户访问的是login.jsp应该放行
String uri = req.getRequestURI();
// System.out.println(uri);
if (this.isEndWith(uri, loginStrs)) {
chain.doFilter(request, response);
} else if(this.isEndWith(uri, includeStrs)){
//如果用户访问的是css jpg js 等等,也要放行
chain.doFilter(request, response);
}else {
System.out.println("用户没有登陆");
res.sendRedirect(redirectPage);
}
}
}
/**
* @param uri
* @param regx
* @return
*/
private boolean isEndWith(String uri,String [] regx){
boolean flag=false;
for (String string : regx) {
if(uri.endsWith(string)){
flag=true;
break;
}
}
return flag;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
redirectPage = filterConfig.getInitParameter("redirectPage");
loginStr = filterConfig.getInitParameter("loginStr");
loginStrs=loginStr.split(",");
includeStr=filterConfig.getInitParameter("includeStr");
includeStrs=includeStr.split(",");
}
}
web.xml配置
<!-- 登陆过滤器 -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>LoginFilter包名</filter-class>
<!-- 如果用户没用登陆,就重定向到login.jsp -->
<init-param>
<param-name>redirectPage</param-name>
<param-value>login.jsp</param-value>
</init-param>
<init-param>
<param-name>loginStr</param-name>
<param-value>login.jsp,login.action</param-value>
</init-param>
<init-param>
<param-name>includeStr</param-name>
<param-value>.css,.js,.jpg,.png,.gif</param-value>
</init-param>
</filter>
9.文件上传
第一步:准备相关的第三方jar包 File IO
第二步:写表单
第三步:得到上传的目录和临时目录
注意,文件上传是把文件上传到tomcat服务器的目录里面
//得到上传的目录和临时目录 String uploadPath=this.getServletContext().getRealPath("/upload"); String uploadTempPath=this.getServletContext().getRealPath("/upload/temp"); |
第四步:查看当前表单是否是文件上传的表单
boolean isFormData=ServletFileUpload.isMultipartContent(request); |
第五步:开始文件上传
//1, 创建文件工厂
DiskFileItemFactory factory=new DiskFileItemFactory();
//2,设置缓冲区大小
factory.setSizeThreshold(1024*1024);//1M
//3,设置文件上传的临时目录
factory.setRepository(new File(uploadTempPath));
//4,在厂里面创建一个文件上传的流水线
ServletFileUpload fileUpload=new ServletFileUpload(factory);
//5,设置单个文件上传的大小限制
fileUpload.setFileSizeMax(10*1024*1024);//10M
FileItemIterator iterator=fileUpload.getItemIterator(request); while(iterator.hasNext()){ //得到单个表单控件的流 text password textarea file FileItemStream stream=iterator.next(); //判断是否为表单控件 if(!stream.isFormField()){ //找到文件了 // System.out.println(stream.getFieldName());//得到表单name // System.out.println(stream.getContentType());//得到文件类型 // System.out.println(stream.getName());//得到文件名 img1.jpg //取到当前文件的流 InputStream is=stream.openStream(); //创建输出流把上面的这个输入流写到服务器硬盘里面 String fileName=stream.getName(); String end=fileName.substring(fileName.lastIndexOf(".")); String filePath=uploadPath+"/"+RandomStrUtils.getRondomName()+end; System.out.println(filePath); //D:\\DevTools\\server\\apache-tomcat-7.0.34\\webapps\\bjsxt\\upload\\img1.jpg BufferedOutputStream os=new BufferedOutputStream(new FileOutputStream(filePath)); byte[] b=new byte[1024]; int len=0; while((len=is.read(b))!=-1){ os.write(b, 0, len); os.flush(); } os.close(); is.close(); } }
|
注意点:文件上传之后,要更改文件存放到服务器里面的名字
10.文件下载
private static final long serialVersionUID = 1L;
private UserDAO dao=new UserDAOImpl();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到传过来的ID
int id=Integer.parseInt(request.getParameter("id"));
//通过ID找到路径
User user=dao.queryById(id);
//路径
String path=user.getTitle();//upload
//得到服务器的发布路径
String proPath=this.getServletContext().getRealPath("/");
String downloadPath=proPath+path;
File file=new File(downloadPath);
//判断文件是否存在
if(file.exists()){
//设置下载文件的类型
response.setContentType("application/x-msdownload");
//设置下载文件的名称
response.setHeader("Content-Disposition", "attachment; filename=\"" +
user.getOldname() + "\"");
//得到文件的长度
int len=(int)file.length();
if(len>0){
//开始下载
FileInputStream fis=new FileInputStream(file);
//从响应里面得到Servlet的输出流
ServletOutputStream sos=response.getOutputStream();
byte [] b=new byte[1024*1024];
int len2=0;
while((len2=fis.read(b))!=-1){
sos.write(b, 0, len2);
sos.flush();
}
//关流
sos.close();
fis.close();
}
}else{
request.getRequestDispatcher("error.jsp").forward(request, response);
}
}
11.图形验证码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="login.action" method="post">
<input type="text" name="authcode"> <img src="authcode.action" width="100",height="35" onclick="this.src=this.src+'?'">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
工具类
/**
* 生成图型验证码的工具类
*
* @author Arvin
*
*/
public class AuthCodeUitls {
// 验证码的字符个数
private static int AUTHCODE_LENGTH = 4;
// 数组字典
private static char[] CHARS = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
// 颜色字典
private static Color[] COLORS = { Color.BLACK, Color.GREEN, Color.YELLOW,
Color.PINK, Color.BLUE, Color.RED };
// 随机数对象
private static Random random = new Random();
/**
* 生成一个字符串 长度为验证码的长度
*/
public static String getAuthCode() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < AUTHCODE_LENGTH; i++) {
sb.append(CHARS[random.nextInt(CHARS.length)]);
}
return sb.toString();
}
// 配置生成图片的常量
// 1, 确定每个字符的宽度 int singleauthcode_width=20
private static final int SINGLEAUTHCODE_WIDTH = 20;
// 2, 确定每个字符的高度 int singleauthcode_height=30
private static final int SINGLEAUTHCODE_HEIGHT = 30;
// 3, 确定每个字符之间的间距 int singleauthcode_gap=5;
private static final int SINGLEAUTHCODE_GAP = 5;
// 4, 得到图片的宽度 int img_width= (singleauthcode_width+ singleauthcode_gap)*
// authcode_length
private static final int IMG_WIDTH = AUTHCODE_LENGTH
* (SINGLEAUTHCODE_WIDTH + SINGLEAUTHCODE_GAP);
// 5, 得到图片的高度 int img_height=30
private static final int IMG_HEIGHT = SINGLEAUTHCODE_HEIGHT;
// 生成图片
/**
*
* @param authcode
* @return
*/
public static BufferedImage getAuthImg(String authcode) {
// 设置图片的宽度,高度,类型
BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
BufferedImage.TYPE_INT_RGB);
// 得到图片上的一个画笔
Graphics g = img.getGraphics();
// 设置画毛笔的颜色 白色
g.setColor(Color.WHITE);
// 在图片填充一个矩形 设置宽 高
g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
// 设置字体 字体类型 字体样式 字体的大小
g.setFont(new Font("宋体", Font.BOLD, SINGLEAUTHCODE_HEIGHT));
// 设置画笔的颜色 去画字符
g.setColor(Color.BLACK);
for (int i = 0; i < authcode.toCharArray().length; i++) {
// 随机设置画笔的颜色
g.setColor(COLORS[random.nextInt(COLORS.length)]);
// 得到相应下标的字符
char c = authcode.charAt(i);
// 把字符画到图片上
g.drawString(c + "", i
* (SINGLEAUTHCODE_WIDTH + SINGLEAUTHCODE_GAP)
+ SINGLEAUTHCODE_GAP / 2, IMG_HEIGHT);
}
g.setColor(Color.GRAY);
// 干扰素
for (int i = 0; i < 15; i++) {
int x = random.nextInt(IMG_WIDTH);
int y = random.nextInt(IMG_HEIGHT);
int x2 = random.nextInt(IMG_WIDTH);
int y2 = random.nextInt(IMG_HEIGHT);
g.drawLine(x, y, x + x2, y + y2);
}
return img;
}
}
生成图形验证码的Servlet
/**
* 生成图形验证码的Servlet
* @author Arvin
*
*/
public class AuthCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html");
//1,生成一个随机字符串
String authcode=AuthCodeUitls.getAuthCode();
//把字符串放到session里面
request.getSession().setAttribute("authcode", authcode);
//调用AuthCodeUitls工具里面的一个方法,生成一个图片,,再把图片返回到客户端
BufferedImage img=AuthCodeUitls.getAuthImg(authcode);
//响应到客户端
try {
ImageIO.write(img, "JPEG", response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}