踮起回望,有关Servlet的笔记

Ⅰ.前言

Servlet作为服务端的重要角色,虽然在日常的WEB项目开发中已经失去它的身影,但是我们所使用的框架仍然是Servlet在起着重要的作用,只不过是加以封装了,比如Spring MVC的底层,前端控制器DispatcherServlet就是继承HttpServlet的,所以还是很有必要了解下Servlet的.

这里写图片描述


Ⅱ.Servlet配置多个映射路径

Servlet配置多个映射路径的

//方式一
<!--  配置Servlet的映射信息  -->
<servlet-mapping>
    <servlet-name>test1</servlet-name>
    <url-pattern>/a.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>test1</servlet-name>
    <url-pattern>/b.do</url-pattern>
</servlet-mapping>

//方式二
<servlet-mapping>
    <servlet-name>test1</servlet-name>
    <url-pattern>/a.do</url-pattern>
    <url-pattern>/c.do</url-pattern>
</servlet-mapping>

Servlet映射路径的通配符

映射路径的通配符其实就是 ” * ” , ” * “可以匹配任意的路径

注意:通配符使用只能有两种固定的格式:一种格式是” * .扩展名 “,另一种格式是以正斜杠(/)开头并以“/* ”结尾

通配符要注意的细节:

  1. 如果你需要匹配一个拓展名那么就必须以*开头,
  2. 通配符出现在中间位置的时候,“*”号只不过就是一个普通的字符而已。
  3. “/”开头的路径的优先级要高于“*”号开头的优先级。

Ⅲ.HttpRequest对象与HttpResponse对象

HttpRequest

HttpRequest作为servlet类里一个非常重要的对象,主要用于获取客户端传递的信息等,当客户端通过HTTP协议访问服务器时,HTTP请求中的所有信息都封装在这个对象中,我们则可以通过这个对象进行获取客户端的信息,获取信息:

  • 通过request对象可以获取到客户端的请求头/请求行/请求参数

    request.getMethod()             //请求的方式
    request.getRequestURI()         //请求的资源路径
    request.getProtocol()           //请求的协议
    
    request.getHeader("user-agent")                         //获取请求所使用的浏览器
    request.getHeader("referer")                            //防盗链
    
    Enumeration<String> e = request.getHeaderNames()        //获取请求头信息                           
    
    request.getParameter("userName")                        //通过请求参数获取请求值
    String[] hobit = request.getParameterValues("hobit")    //请求参数对应多个值
    
  • request作为域对象传递数据

    域对象:指该对象可以存储数据,而且可以把该数据传递给其他的Servlet或jsp.

    备注:下面有个demo记录request是如何传递数据的

HttpResponse(另外再记录)


Ⅳ.ServletContext对象

简介:

Tomcat服务器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用; ServletContext在一个项目中只有一个

作用:

  • 1.获取当前应用的路径

    public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //获取当前的工程ServletContext
            ServletContext context = this.getServletContext();
            System.out.println("当前工程:"+ context.getContextPath() );
            //请求重定向
            response.sendRedirect(context.getContextPath()+"/login.html");
        }   
    
  • 2.获取配置参数

    <!-- web.xml文件 ,配置一个全局使用的码表  -->
    <context-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
    </context-param>
    
    //Servlet文件
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        ServletContext context  = this.getServletContext();
        //根据配置参数的名字,获取配置参数
        String character = context.getInitParameter("charset");
        response.setContentType("text/html;charset="+character);
    
        PrintWriter out = response.getWriter();
        out.write("<p>根据配置参数的名字,获取配置参数</p>");
    }
    
  • 3.作为域对象使用

    api:
    
         HttpServlet.getServletContext()            //获取ServletContext  
         servletContext.setAttribute("key",value)   //往servletContext存数据
         context.getAttribute("key")                //从servletContext取数据
    
    
    //往ServletContext中存储数据,SetDataServlet.java
        public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            ArrayList<String> list = new ArrayList<String>();
            list.add("狗娃");
            list.add("狗剩");
            list.add("铁蛋");
            //存储数据
            context.setAttribute("list",list);
        }
    
    
    //往ServletContext中取数据,GetDataServlet.java
        public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
            ServletContext context = this.getServletContext();
            //从servletcontext中获取数据
            ArrayList<String> list = (ArrayList<String>) context.getAttribute("list");
            System.out.println("获取到的数据:");
            for(String item : list){
                System.out.println("\t"+item);
            }
        }
    
  • 4.获取资源文件

    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
        ServletContext context = this.getServletContext();
        InputStream inputStream = context.getResourceAsStream("/WEB-INF/classes/images/3.jpg"); //  "/"则代表了当前的工程
    
        byte[] buf = new byte[1024];
        int length = 0; 
        OutputStream out = response.getOutputStream();
    
        while((length = inputStream.read(buf))!=-1){
            out.write(buf,0,length);
        }
        inputStream.close();
    }
    

Ⅴ.小例子

实现登录的效果(request作为域对象传递数据)

login.html


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>登录</title>
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
      </head>

      <body>
        <form action="/wyk02/loginServlet" method="post">
            用户名:
            <input type="text" name="user">

            密码   :
            <input type="password" name="pword"/>

            <input type="submit" value="登录"/>

        </form>
      </body>
    </html>

message.jsp


    <%@ page language="java" import="com.wyk.test01.model.*" 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>登录结果展示</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>

        <%
            String status = (String)request.getAttribute("flag");
            User user = (User)request.getAttribute("user");
            if(status.equals("success")){
                out.write("<h1>恭喜 "+ user.getUser() +"用户,登录成功 </h1>");
            }else if(status.equals("failure")){
                out.write("<h1>不好意思,不存在 " + user.getUser() +"用户</h1>");
            }
         %>
      </body>
    </html>

LoginServlet.java


    /**
     *  request作为域对象的实例
     */
    public class LoginServlet extends HttpServlet {

        private static List<User> users = new ArrayList<User>();
        static{
            //假数据 
            users.add(new User("admin","admin"));
            users.add(new User("admin","123"));
            users.add(new User("ly","123"));
        }

        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }

        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {

            request.setCharacterEncoding("UTF-8");      //解决编码问题

            String userName = request.getParameter("user");
            String pasword = request.getParameter("pword");

            User user = new User(userName,pasword);
            request.setAttribute("user",user);
            if(users.contains(user)){
                //账号存在
                request.setAttribute("flag", "success");
            }else{
                //不存在
                request.setAttribute("flag","failure");
            }
            //请求转发
            request.getRequestDispatcher("/message.jsp").forward(request, response);

            /**
             使用请求重定向,这里会有问题,message会取不出request存储的信息
             response.sendRedirect("/day08/message.jsp");       
            */
        }
    }

User.java


    /**
     * 实体bean,存储用户信息
     */
    public class User {
        private String userName;
        private String password;
        public User(String user, String password) {
            super();
            this.userName = user;
            this.password = password;
        }
        public String getUser() {
            return userName;
        }
        public void setUser(String user) {
            this.userName = user;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        @Override
        public boolean equals(Object obj) {
            User user = (User)obj;
            return this.userName.equals(user.userName) && this.password.equals(user.password);
        }
    }

Ⅵ.补充

通过servlet获取请求信息,经常无可避免会遇到乱码的问题,怎么解决?

因为请求方式的不同,乱码的解决方法又有所不同.如果请求方式是get,那么请求信息会出现在请求行;如果请求方式是post,那么请求信息会出现在实体内容上。所以得分两种(具体的看代码)


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String method = request.getMethod();
        if("post".equalsIgnoreCase(method)){
            /*request对象默认使用的码表是: iso8859-1
            setCharacterEncoding 该方法的作用是通知request对象获取实体内容的时候使用UTF-8码表解码。*/

            request.setCharacterEncoding("UTF-8");
            String userName = request.getParameter("userName");
            System.out.println("用户名:"+ userName);
        }else if("get".equalsIgnoreCase(method)){
            String userName = request.getParameter("userName");
            //使用userName找iso8859-1码表进行重新编码,找回原来的数字
            byte[] buf = userName.getBytes("iso8859-1");
            //使用utf-8解码即可
            userName = new  String(buf,"UTF-8");
            System.out.println("用户名:"+ userName);

        }

请求重定向与请求转发的区别

  • 如果是使用请求重定向的时候浏览器的URL地址栏是会发生变化的,如果是使用请求转发URL地址栏是不会发生变化的;

  • 请求重定向新的请求是由浏览器发出的,这个过程是创建了两个request对象,请求转发的请求是由tomcat服务器发出的,这个过程只是会创建一个requet对象 (注意:请求重定向时,如果request又作为域对象来使用,这时就牵扯到另外的一个servlet或jsp,请求重定向会导致另外的servlet或jsp拿不到request存储的数据);

  • “/”如果是给服务器查看,那么“/”则代表了localhost:8080/工程名,如果“/”是给浏览器查看,那么“/”则代表了localhost:8080/而已

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值