Servlet

2018-12-21  本文已影响0人  微笑中的你

Servlet 是运行在服务端的Java小程序,是sun公司提供的接口规范
用来处理客户端请求,响应给浏览器的动态资源
servlet的实质就是Java代码,通过java的API动态的向客户端输出内容
编译成字节码,放到服务器上执行。
编写程序时,不需要有main函数了。当前发送一个请求的时候,服务器就会按照一定规则调用编写的代码。

第一个servlet
public class FirstServlet implements Servlet{
    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("------init");
    }
    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        System.out.println("------service");
        HttpServletResponse httpResponse = (HttpServletResponse)response;
        httpResponse.getWriter().write("aaaaaaaaaaaaaaa");
    }
    @Override
    public void destroy() {
        System.out.println("------destroy");
    }
    @Override
    public ServletConfig getServletConfig() {
        System.out.println("------getServletConfig");
        return null;
    }
    @Override
    public String getServletInfo() {
        System.out.println("------getServletInfo");
        return null;
    }
}

web.xml文件中配置servlet
  <servlet>
    <servlet-name>myservlet</servlet-name>
    <servlet-class>com.lz.servlet.FirstServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>myservlet</servlet-name>
    <url-pattern>/first</url-pattern>
  </servlet-mapping>

在浏览器中输入效果如图1:


图1

原理:在浏览器输入地址回车后。tomcat就会解析该地址,然后就会到web.xml中去匹配该地址,找到servle映射first,然后找到servlet的对应类名称,就会创建对应对象。内部机制是用反射实现的。

类的加载时机

当程序要使用某个类时,如果该类还未加载到内存中。系统会通过加载、连接
初始化三步来实现对这个类进行初始化。

加载时机:创建类的实例,访问类的静态变量和赋值,调用类的静态方法,初始化某个类的子类,使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。

类加载器 classLoader

负责将.class文件加载到内存中,并生成对应的Class对象。
分类:

反射

运行状态下,可以获取任意类的所有属性和方法。
对于任意对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
想要使用反射,必须的要获取字节码文件。

获取字节码文件

代码1

        (获取字节码)
        Class c1 = Class.forName("com.lz.reflect.Person");
        通过字节码创建对象
        Person p = (Person) c1.newInstance();
        p.setName("phonegg");
        p.setEmail("phonegg@foxmail.com");
        p.show();
        
        通过有参数的构造器来创建对象
        Constructor c = c1.getConstructor(String.class, String.class);
        Person p2 = (Person) c.newInstance("gjj","gjj@qq.com");
        p2.show();

HttpServletRequest

@WebServlet("/request")
public class RequestServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        System.out.println("------------获取请求信息------------");
请求行
        获取请求方式
        String method = request.getMethod();
        System.out.println(method);
        
           获取请求Uri
        String requestUri = request.getRequestURI(); //从项目开始
        System.out.println(requestUri); 
        GET请求   uri  /Servlet/request     
        POST请求  uri  /Servlet/request     
        String requestUrl = request.getRequestURL().toString(); 
        System.out.println(requestUrl);
        GET请求   url  http://localhost:8080/Servlet/request
        POST请求  url  http://localhost:8080/Servlet/request
        
        请求参数
        String queryString = request.getQueryString();
        System.out.println(queryString);
        GET请求   queryString  name=aaa&age=1
        GET请求   queryString  null
        
        当前项目根路径
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        

        System.out.println("----------请求头信息------------");
请求头
        获取所有请求头名称
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            System.out.println(" name: " + headerNames.nextElement());
        }
        
        System.out.println("----------------------");

        获取指定的请求头
        String header = request.getHeader("referer"); //获取访问来源
        System.out.println(" referer: "+header);
        
//      if (header.equals("http://localhost:8080/Servlet/request.html")) {
//          response.sendRedirect("/Servlet/request.html");
//      }
//      
        System.out.println("----------------------");
        
        获取所有请求头名称和值
        Enumeration<String> headerNamesValues = request.getHeaderNames();
        while (headerNamesValues.hasMoreElements()) {
            String name = headerNamesValues.nextElement();
            String value = request.getHeader(name);
            System.out.println(" name: " + name+ ", value:"+value);
        }

          System.out.println("---------请求体-------------");
请求体
        获取请求参数
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String sex = request.getParameter("sex");
        System.out.println("name:"+name+", age:"+age+", sex:"+sex);
        String[] hobby = request.getParameterValues("hobby");
        System.out.println("爱好:"+Arrays.toString(hobby));
        
        System.out.println("----------------------");

        获取所有请求参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            System.out.println(parameterNames.nextElement());
        }
        
        System.out.println("----------------------");

        获取所有请求参数键值对
        Map<String, String[]> param = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : param.entrySet()) {
            String key = entry.getKey();
            String[] values = entry.getValue();
            System.out.println("key="+key+", valuse="+Arrays.toString(values));
        }
    }
}

form表单提交中文乱码

//发送form请求时,会对请求参数进行编码,格式为ISO8859-1 不支持中文

String sex = request.getParameter("sex");
System.out.println(sex);
byte[] bytes = sex.getBytes("ISO8859-1");
String sexUtf = new String(bytes, "utf-8");
System.out.println(sexUtf);
request.setCharacterEncoding("UTF-8");

HttpServletResponse

@WebServlet("/response")
public class ResponseServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        默认编码为 ISO 8859-1 并不支持中文
        response.setCharacterEncoding("UTF-8");
        告诉浏览器 使用编码格式
        response.setHeader("Content-Type", "text/html;charset=UTF-8");
        第一要写在最前面,否则可能仍为乱码。
        response.getWriter().write("你真好");

        设置响应状态码
        response.setStatus(302);
        
        添加响应头
        response.addHeader("name", "lz");
        response.addIntHeader("age", 20);
        response.addDateHeader("my-date", new Date().getTime());
        
        修改响应头
        response.setHeader("name", "lxf");
        
        请求重定向:
        response.setHeader("location", "/Servlet/login");
        response.sendRedirect("/Servlet/login");
        
        定时重定向  各3秒后重定向
        response.setHeader("refresh", "3;url=/Servlet/login");

        请求转发
        RequestDispatcher dispatcher = request.getRequestDispatcher("/s2");
        dispatcher.forward(request, response);

    }
}

重定向 和 转发 对比

ServletContext

@WebServlet("/context")
public class ContextServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletContext context = getServletContext();
        System.out.println(context);
        获取WebContent下文件
        String aPath = context.getRealPath("a.text");
        System.out.println("a.path--"+aPath);
        
        获取WEB-INF下文件  拼接路径
        String bPath = context.getRealPath("WEB-INF/b.txt");
        System.out.println("bPath----"+bPath);

        
        获取src下的文件 先加载该文件
        String cPath = this.getClass().getClassLoader().getResource("c.txt").getPath();
        System.out.println(cPath);
    }

}
servlet中以二进制读取图片
@WebServlet("/img")
public class ImgServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String path = getServletContext().getRealPath("noti.jpg");
        
        输入流
        FileInputStream in = new FileInputStream(path);
        
        输出流
        ServletOutputStream out = response.getOutputStream();
        
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = in.read(b)) != -1) {
            System.out.println(len);
            System.out.println(Arrays.toString(b));
            out.write(b, 0, len);
        }

    }
}

servlet 实现下载
@WebServlet("/download")
public class DownLoadServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

提取需要下载的文件名
        String filename = request.getParameter("filename");
        System.out.println(filename);
        //默认会对参数进行 ISO8859-1 编码, 中文名称的文件就会乱码
        
转回为二进制位
        byte[] bname = filename.getBytes("ISO8859-1");
        再使用utf-8进行编码
        filename = new String(bname, "utf-8");
        System.out.println(filename);
        
设置MIME类型, 即文件类型尾缀
        String mimeType = getServletContext().getMimeType(filename);
        response.setContentType(mimeType);
        
告诉浏览器以附件打开
        response.setHeader("Content-Disposition", "attachment;"); 
        修改下载是文件名称
        response.setHeader("Content-Disposition", "attachment;filename="+filename); 

根据不同浏览器进行中文编码, 因为不同浏览器默认编码不同
        String agent = request.getHeader("User-Agent");
        String encodedName = "";
        if (agent.contains("MSIE")) {
            如果是IE浏览器
            encodedName = URLEncoder.encode(filename, "utf-8");
            System.out.println(encodedName);
            encodedName = encodedName.replace("+", " ");
            System.out.println(encodedName);
        } else if (agent.contains("Firefox")) {
            如果是火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            encodedName = "=?utf-8?B?"+base64Encoder.encode(filename.getBytes("utf-8"))+"?=";
        } else {
            其他浏览器编码
            encodedName = URLEncoder.encode(filename, "utf-8");
        }
        response.setHeader("Content-Disposition", "attachment;filename="+encodedName); 

        以流形式读取
        String path = getServletContext().getRealPath(filename);
        FileInputStream in = new FileInputStream(path);
        ServletOutputStream out = response.getOutputStream();
        
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = in.read(b)) != -1) {
            out.write(b, 0, len);
        }
        关闭流是否资源
        in.close();
    
    }
}

Cookie

        Cookie age = new Cookie("age", "100");      
        
        //设置cookie的保存时间
        age.setMaxAge(60);
        //设置cookie携带路径。。。在我工程路径下都可以携带cookie
//      age.setPath("/Cookie_Session");
        //默认情况下,url请求头中会携带父级级路径中的cookie和同级路径的cookie
        response.addCookie(age);
        
        //删除cookie的保存时间修改为0即可。
//      age.setMaxAge(0);
        
        
        //获取指定cookie 比较cookie名字
        Cookie[] cookies = request.getCookies();
        if (cookies!=null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("age")) {
                    System.out.println(cookie.getValue());
                }
            }           
        }

Session

session 的创建

第一次执行request.getSession()时创建。

session 的销毁

        session 判断是否存在的依据
    通过cookie中携带的JSessionId判断
    
        HttpSession session = request.getSession();
        String name = (String) session.getAttribute("name");
        Integer age = (Integer) session.getAttribute("age");
        
        session.invalidate();
        
        System.out.println("姓名:"+name+", 年龄:"+age);

Cookie Session 对比

上一篇 下一篇

猜你喜欢

热点阅读