代码改变世界

servlet

2018-07-05 18:57  yelena  阅读(143)  评论(0编辑  收藏  举报

servlet:运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源

本质上是java代码,通过api动态向客户输出内容

包含三个技术:servlet技术   filter技术   listener技术

实现servlet接口的方式

1、创建实现类实现servlet接口

2、重写方法---重点是service方法(需要重写的方法太多)

3、在xml中进行servlet配置

1、继承httpservlet类

2、重写doget和dopost方法

3、在xml中进行servlet配置

方法

init()方法:servlet对象创建的时候执行

service()方法:包含请求和回应对象,每次请求都会执行,在httpservlet中分为doget()和dopost()方法

destroy()方法:servlet销毁的时候执行

servlet的生命周期:创建-----默认第一次访问servlet时创建该对象,但是在servlet配置时,加上<load-on-startup>,在服务器启动时创建;销毁-----服务器关闭

servlet中的元素url-pattern的配置方式

完全匹配:正常写法;目录匹配:最后目录用*代替;扩展名匹配:扩展名前面用*代替;缺省匹配:只有一个/,所有地址访问都不行时,缺省servlet负责接收

 servletcontext:web应用的环境(上下文)对象,只有一个

 生命周期:该web应用被加载(服务器启动)时创建,该web应用被卸载(服务器关闭)时销毁

构造方法:getservletcontext()方法,直接使用此方法

使用方式

1、获得全局配置的初始化参数(首先用context-param标签配置全局参数)

//获取ServletContext对象
        ServletContext sc = getServletContext();
        //获取全局的初始化参数
        String init = sc.getInitParameter("driver");
        System.out.println(init);

2、获得web应用中任意资源的绝对路径(写一个相对于本web应用的路径,得到绝对路径,这个相对路径是在磁盘中保存的路径,不是eclipse中的路径显示)

//给一个资源的相对路径,获取对应的绝对路径
        //a.txt在src下
        String patha = sc.getRealPath("WEB-INF/classes/a.txt");
        System.out.println(patha);
        //b.txt在WebContent下的WEB-INF下
        String pathb = sc.getRealPath("WEB-INF/b.txt");
        System.out.println(pathb);
        //c.txt在WebContent下
        String pathc = sc.getRealPath("c.txt");
        System.out.println(pathc);
        //建在本工程下的没复制到服务器,也获取不到

3、servletcontext是一个域对象(可以存储东西,整个web应用中的资源都可以去里面存取东西)

public class Servlet01 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();
        context.setAttribute("name", "张三");
    }
public class Servlet02 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = getServletContext();
        String name = (String)context.getAttribute("name");
        System.out.println(name);
    }

httpservletresponse类

定义:doget()方法和dopost()方法中的参数类型,是servletresponse(service方法中的参数类型)的子接口,功能更强大

响应分为响应行 响应头 响应体 ,通过此类可以分别设置

设置响应行:

setstatus()设置状态码

设置响应头:

setheader(String name,String value),一般都是传两个字符串类型的参数

重定向(两次请求,地址会变化)

//设置状态码
        //response.setStatus(302);
        //设置响应头Location
        //response.setHeader("Location", "/WEB03/Servlet03");
        //开发中专门用于重定向的方法
        response.sendRedirect("/WEB03/Servlet03");

 定时刷新(可以头设置,也可以jsp里设置)

response.setHeader("refresh", "5;url=http://www.baidu.com");
        response.getWriter().write("hello dandan...");
var time = 5;
window.onload = function(){
    var second = document.getElementById("second");
    timer = setInterval(function(){
        second.innerHTML = time;
        time--;
        if(time==0){
            clearInterval(timer);
            location.href="http://www.baidu.com";
        }
    }, 1000);
}
恭喜你,注册成功,<span style ="color:red" id ="second">5</span>秒后跳转,
    如不跳转,点击<a href ="http://www.baidu.com">这里</a>

中文乱码问题

//设置缓冲区的编码
//        response.setCharacterEncoding("UTF-8");
//        //告知客户端用utf-8解码
//        response.setHeader("Content-Type", "text/html;charset=utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("中国");

字节流的获取

getoutputstream():获得字节流,通过此流向response缓冲区写入字节,然后由tomcat把内容组成http响应返回给浏览器

下载图片,视频(直接在浏览器中打开)

//获得字节输出流
        ServletOutputStream out = response.getOutputStream();
        //确定数据源
        String realpath = getServletContext().getRealPath("dameinv.jpg");
        FileInputStream fis = new FileInputStream(realpath);
        byte[] bytes = new byte[1024];
        int len =0;
        while((len=fis.read(bytes))!=-1){
            out.write(bytes, 0, len);
        }
        fis.close();
    }

正确的下载

// 获得下载的文件名
        String filename = request.getParameter("filename");
        // 解决中文乱码问题
        filename = new String(filename.getBytes("ISO8859-1"), "UTF-8");
        // 获取请求头 User-Agent
        String agent = request.getHeader("User-Agent");
        String filenameEncoding = "";
        // 根据不同的浏览器,进行编码(模板复制,不需要记忆)
        if (agent.contains("MSIE")) {
            // IE浏览器
            filenameEncoding = URLEncoder.encode(filename, "utf-8");
            filenameEncoding = filenameEncoding.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filenameEncoding = URLEncoder.encode(filename, "utf-8");
        }
        // 要下载的文件类型--客户端通过文件的mime类型区分文件的类型
        response.setContentType(this.getServletContext().getMimeType(filename));
        // 告诉客户端该文件不能直接解析,而是以附件的形式打开
        response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoding);
        // 获得文件的绝对路径
        String path = this.getServletContext().getRealPath("download/" + filename);
        // 创建输入流
        FileInputStream fis = new FileInputStream(path);
        ServletOutputStream out = response.getOutputStream();
        int len = 0;
        byte[] bytes = new byte[1024];
        while ((len = fis.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        fis.close();

setcontenttype(getservletcontext().getmime(filename))

setheader(content-dispositon,attachment;filename=)

response获得的流不需要手动关闭,web容器(tomcat容器)会帮助我们关闭,只需关闭我们自己new的流

getWriter和getOutputStream不能同时调用

重定向语句一般作为终结代码

 

 

httpservletrequest类:response中是set,而在request中是get

获得请求行中的数据

获得请求方式

//获得请求方式
        String method = request.getMethod();
        System.out.println(method);

获得请求资源地址

//获得相对路径
        String uri = request.getRequestURI();
        //获得绝对路径
        StringBuffer url = request.getRequestURL();
        System.out.println(uri);
        System.out.println(url);
        //获得项目名称
        String path = request.getContextPath();
        System.out.println(path);
        //get提交方式 url后面的参数
        String query = request.getQueryString();
        System.out.println(query);
        //获取访问者的ip地址
        String ip = request.getRemoteAddr();
        System.out.println(ip);

获得请求行头的内容

获得某个请求头

String header = request.getHeader("User-Agent");
        System.out.println(header);

获得所有的请求头:返回一个enumeration枚举对象

Enumeration<String> en = request.getHeaderNames();
        while(en.hasMoreElements()){
            String headName = en.nextElement();
            String headValue = request.getHeader(headName);
            System.out.println(headName+":"+headValue);
        }

referer:监测盗链

String referer = request.getHeader("referer");
        if(referer!=null&referer.startsWith("http://localhost:")){
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("擘画新时代");
        }else{
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("盗链者,丢人");
        }

获取表单中的数据

getparameter():获取单个表单数据   getparametervalues():获得多个表单数据   getparametermap():获取所有表单数据

//获取单个表单数据
        String username = request.getParameter("username");
        String password = request.getParameter("pwd");
        System.out.println(username);
        System.out.println(password);
        //获取多个表单数据
        String[] hobby = request.getParameterValues("hobby");
        for(String str:hobby){
            System.out.println("hobby   "+str);
        }
        //获取所有表单数据
        Map<String,String[]> map = request.getParameterMap();
        Set<String> set = map.keySet();
        for(String str:set){
            String key = str;
            String[] value = map.get(key);
            System.out.println(key);
            for(String s:value){
                System.out.println(s);
            }
            System.out.println("-----------------------");
        }
    }

请求转发(1次请求,地址栏不会变化,对request域的使用,只能访问内部资源,转发效率高)

重定向(2次请求,地址栏变化,可以访问外部资源)

//向request中存值
        request.setAttribute("name", "wangrognchen");
        //请求转发
        request.getRequestDispatcher("/Servlet02").forward(request, response);
        //response.sendRedirect("/WEB04/Servlet02");
String name =(String)request.getAttribute("name"); 
        response.getWriter().write("hello dandan..."+name);

中文乱码

针对post和get方式有不同的解决办法

request.setCharacterEncoding(“UTF-8”)

parameter = new String(parameter.getBytes(“iso8859-1”),”UTF-8”)

post的解决方式更有效率,一般使用此方法就可,get方式太麻烦