Servlet

目录

1.Servlet生命周期 

2.乱码问题

3.ServletConfig 

4.ServletContext (Servlet上下文)

5.Cookie

6.Session   

7.Servlet的三大作用域

8.过滤器

9.文件上传

10.文件下载

11.图形验证码


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

特点:

  1. 由servlet创建     并发送给浏览器
  2. 保存浏览器里面【可能是硬盘】 
  3. 可以以秒为单位设置cookie的时间
  4. 如果设置有时间cookie就存放硬盘里面
  5. 如果没有设置时间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的三大作用域

  1. 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();
		}
		
	}

}

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值