Tomcat整理记录

1.目录结构

web项目根目录
-- WEB-INF目录
-- web.xml:web项目的核心配置文件
-- classes目录:防止字节码文件的目录 部署后web同级src目录文件放在此处
-- lib:防止依赖的jar包

2. Servlet 接口,定义了Java类被访问的规则(JavaWeb的三大组件之一

1.生命周期

  • init 创建 只执行一次,在内存中也只存在一个对象,是单例
  • service 提供服务,每次访问都会被调用
  • destroy 销毁 服务器正常关闭时调用,被销毁之前执行,一般用于释放资源
    2.访问
web.xml *不建议使用*
    <servlet>
        <servlet-name>demo1</servlet-name>
        <servlet-class>cn.tomcat.web.ServletDemo1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>

3.0使用注解@WebServlet

@WebServlet("/demo2")  ||  @WebServlet(urlPatterns = {"/demo2","/d2"})

3.体系结构
GenericServlet 抽象类:将Servlet接口中除service()的其他方法做了默认空实现
HttpServlet 抽象类:对http协议的一种封装,简化操作:继承HttpServlet复写doGet/doPost方法

3.request和response

1.request 请求消息

//        1.获取请求方式
        String method = req.getMethod();
//        2.获取虚拟目录
        String contextPath = req.getContextPath();
//        3.获取servlet路径
        String servletPath = req.getServletPath();
//        4.获取请求参数
        String queryString = req.getQueryString();
//        5.获取请求的URI
        String requestURI = req.getRequestURI();
//        6.获取请求的URL
        StringBuffer requestURL = req.getRequestURL();
//        7.获取协议及版本
        String protocol = req.getProtocol();
//        8.获取客户机的IP地址
        String remoteAddr = req.getRemoteAddr();
//        9.获取请求头中的某个值 user-agent  referer
        String userAgent = req.getHeader("user-agent");
//        10.获取所有的请求头名称
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String value = req.getHeader(name);
            System.out.println(name + " --> " + value);
        }
//get tomcat 8 将get乱码问题解决了
//post中文会乱码,在获取参数之前设置request的编码(应该跟页面编码保持一致)
req.setCharacterEncoding("utf-8");
// 获取请求参数
Map<String,String[]> map = req.getParameterMap();
req.getParameter("password");

2.response 响应消息
//设置状态码
resp.setStatus();

  • 1xx:接收的请求正在处理,没有接收完成,一段时间后发送1xx状态码
  • 2xx:成功。代表200
  • 3xx:重定向。代表302(重定向)、304(访问缓存)
  • 4xx:客户端错误。代表404(请求路径没有对应资源)、405(请求方式没有对应的doXxx方法)
  • 5xx:服务器端错误。代表500(服务器内部出现异常)

//设置响应头
resp.setHeader(String name,String value);

  • content-type:响应体数据编码格式,编码不一致又会乱码
resp.setHeader("content-type","text/html;charset=utf-8");
OR:
resp.setContentType("text/html;charset=utf-8");
  • content-disposition:以什么格式打开响应体数据。
    {
    in-line :默认值,在当前页面打开
    attachment;filename=xxx :以附件形式打开响应体。见——>文件下载
    }

a.字符输出流 —— 输出字符数据到浏览器

resp.setContentType("text/html;charset=utf-8");
//获取字符输出流 流的默认编码是ISO-8859-1,所以提前设置该流的编码,告诉浏览器该使用的编码
PrintWriter printWriter = resp.getWriter();
//输出数据
//printWriter.write("hello");
printWriter.write("<h1>hello</h1>");

b.字节输出流 —— 文件下载

//获取文件名称
String filename = req.getParameter("filename");
ServletContext servletContext = this.getServletContext();
//找到图片img文件下路径
String filepath = servletContext.getRealPath("/img/" + filename);
//字节流关联图片
FileInputStream fileInputStream = new FileInputStream(filepath);

//获取文件类型
String mimeType = servletContext.getMimeType(filename);
//设置响应头content-type
resp.setContentType(mimeType);
//设置打开方式
resp.setHeader("content-disposition","attachment;filename=" + filename);
ServletOutputStream outputStream = resp.getOutputStream();
byte[] buff = new byte[10*1024];
int len = 0;
while ((len = fileInputStream.read(buff)) != -1) {
    outputStream.write(buff,0,len);
}
fileInputStream.close();
//如果下载文件名中有中文乱码,那么得兼容浏览器了:
    public static String getFileName (String agent,String filename) {
        try {
            if (agent.contains("MSIE")) {
                filename = URLEncoder.encode(filename,"utf-8");
                filename = filename.replace("+"," ");
            } else if (agent.toLowerCase().contains("firefox")){
                BASE64Encoder base64Encoder = new BASE64Encoder();
                filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {
                filename = URLEncoder.encode(filename,"utf-8");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            
        }
        
        return filename;
    }

4.转发和重定向

1.转发 forward

  • 转发地址路径不变
  • 转发只能访问当前服务器下的资源
  • 转发是一次请求,可以使用request对象来共享资源
req.setAttribute("username","传递的值案例");
//请求转发
req.getRequestDispatcher("/demo5").forward(req,resp);
//then:
Object username = req.getAttribute("username");

2.重定向 redirect

  • 地址路径改变
  • 可以访问其他服务器的资源
  • 重定向是两次请求,不能使用request对象来共享资源
//设置状态码302,设置响应头location
resp.setStatus(302);
resp.setHeader("location","/test/demo5");
可简写为:
*resp.sendRedirect("/test/demo5");*
*resp.sendRedirect("https://www.baidu.com");*

5.ServletContext

整个web应用,可以和程序的容器(服务器)来通信
作用:

  • 获取MIME 类型:在互联网通信过程中定义的一种文件数据类型
    格式:大类型/小类型 text/html image/jpeg
  • 域对象:共享数据
    ServletContext对象范围:所有用户所有请求的数据
  • 获取文件的真实路径
//ServletContext context = this.getServletContext();
ServletContext context = req.getServletContext();

//全局数据,使用谨慎
//         context.setAttribute("one","全局共享数据");
//         context.getAttribute("one");
//         context.removeAttribute("one");

//web目录下资源
String filePath = context.getRealPath("/a.txt");
File file = new File(filePath);
//WEB-INF目录下的资源
context.getRealPath("/WEB-INF/b.txt");
//src目录下的资源访问
context.getRealPath("/WEB-INF/classes/c.txt");

6. Filter 过滤器(JavaWeb的三大组件之一

定义一个类,实现接口Filter(import javax.servlet.*;

  • 配置拦截路径 (注解@WebFilter ) 参考servlet
    1. web.xml配置时<filter-mapping>配置在前面的先执行
    2. 注解配置时为从前到后逐字比较(依照字母和数字顺序,值小的先执行)
    3. dispatcherTypes属性
    FORWARD, // 转发访问资源
    INCLUDE,   // 包含访问的资源
    REQUEST,  // 默认值。浏览器直接请求资源
    ASYNC,      // 异步访问资源
    ERROR;      // 错误跳转资源
  • 路径配置方式
    1.具体路径:index.jsp 只有访问index.jsp的时候才会被执行
    2.拦截目录:/user/* 访问user下的所有资源时,过滤器将会被执行
    3.后缀名拦截:*.jsp 访问后缀名为jsp的资源时,过滤器将会被执行
    4.拦截所有资源:访问所有资源时,过滤器将会被执行
  • 过滤器链为栈结构
    过滤器1——>过滤器2——>资源执行——>过滤器2——>过滤器1
System.out.println("过滤器执行了");
//放行——>资源执行
filterChain.doFilter(p_req,servletResponse);
System.out.println("过滤器执行了");

7. Listener 监听器(JavaWeb的三大组件之一

事件监听机制
示例:

@WebListener
public class ListenerDemo implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {

//        一般用来加载资源
        System.out.println("contextInitialized");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

//        销毁资源
        System.out.println("contextDestroyed");
    }
}

8. 验证码示例

        int width = 100;
        int height = 50;
        //创建一个对象,在内存中的图片
        BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //设置图片背景色
        Graphics graphics = bufferedImage.getGraphics();//画笔对象
        graphics.setColor(Color.white);
        graphics.fillRect(0,0,width,height);

        //画边框
        graphics.setColor(Color.red);
        graphics.drawRect(0,0,width-1,height-1);

        graphics.setColor(Color.blue);
        String ss = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        for (int i = 0; i < 4; i++) {

            char c = ss.charAt((int)(Math.floor(Math.random()*ss.length())));
            //画字符
            graphics.drawString(String.valueOf(c),width/4/2 + width/4*i,height/2);
        }

        Random random = new Random();
        for (int i = 0;i < 10; i++) {

            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            //画干扰线
            graphics.drawLine(x1,x2,y1,y2);
        }

        //图片输出
        ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());

9.todo 上传示例

10.使用过滤和代理进行敏感词过滤

        HttpServletRequest p_req = (HttpServletRequest)Proxy.newProxyInstance(request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                if (method.getName().equals("getParameter") && args != null) {

                    String str = (String)method.invoke(request,args);

                    if (str != null && str.contains("笨蛋")) {

                        str = str.replace("笨蛋","***");
                    }
                    return str;
                }

                return method.invoke(request,args);
            }
        });
        System.out.println("过滤器执行了");
        //资源执行
        filterChain.doFilter(p_req,servletResponse);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343