WEB入门浅谈11

Servlet

HttpServletRequest应用

实现一个代码,让浏览器把请求的相关信息全部显示出来

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        String url = req.getRequestURI();
        String protocol = req.getProtocol();
        String query = req.getQueryString();
        Enumeration headNames = req.getHeaderNames();
        String referer = req.getHeader("Referer");
        String host = req.getHeader("Host");
        String contentType = req.getContentType();
        int contentLength = req.getContentLength();
        String contentTyppe2 = req.getHeader("Content-Type");
        String contentLength2 = req.getHeader("Content-Length");
        String string = String.format("<div> method = %s <div>",method) ;
        string += String.format("<div> url = %s <div>",url) ;
        string += String.format("<div> protocol = %s <div>",protocol) ;
        string += String.format("<div> query = %s <div>",query) ;
        string += String.format("<div> headNames = %s <div>",headNames.toString()) ;
        string += String.format("<div> referer = %s <div>",referer) ;
        string += String.format("<div> host = %s <div>",host) ;
        string += String.format("<div> contentLength = %d <div>",contentLength) ;
        string += String.format("<div> contentTyppe2 = %s <div>",contentTyppe2) ;
        string += String.format("<div> contentLength2 = %s <div>",contentLength2) ;
        resp.setContentType("text/html");
        resp.getWriter().write(string);
    }
HttpServletResponse应用

实现一个代码,让浏览器展示页面时,每秒刷新一次

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 需要在http响应的head中加上一个refresh,值为间隔的秒数
        // 构造一个响应页面,这个页面每秒刷新一次
        // 用这个方法 System.currentTimeMillis() 获取当前时间戳
        String str = "<h3>"+   System.currentTimeMillis()   +"</h3>" ;
        resp.setHeader("Refresh","1");
        resp.setContentType("text/html");
        resp.getWriter().write(str);
    }
状态码

设置不同的状态码
404 状态码表示的是Not Found,但是也可以由程序员自己来设定页面内容,Tomcat自身也实现了一个404,平时看到的很多404都是Tomcat自己的页面
很多网站的404都有自己的风格,如:chrome 浏览器的404是一个小游戏,支付宝的404是寻找丢失的儿童
如果我们也想用一下Tomcat的404页面也是可以的:

public class Serlet404 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendError(404,"404040404404");
    }
}

或者直接设置状态码

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(404);
        resp.getWriter().write("Status = 404");
    }

设置一个重定向页面:(注意,此处的url必须是完整的,简写会出错)

public class LocationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(302);
        resp.setHeader("Location","https://www.baidu.com/");
    }
}

或者直接设置:(简化版)

public class LocationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("https://www.baidu.com/");
    }
}
Cookie和Session

客户端进行身份验证,把身份信息通过请求发送给服务器
服务器收到请求,根据信息验证身份,分配一个Session对象,并生成一个SessionId,通过响应中的Set-Cookie属性发送给客户端
客户端拿到Set-Cookie的值,就会保存到浏览器本地
再次验证就会自动带上之前Cookie中保存的值,服务器通过Cookie的值就可以查询用户的身份信息了
SetCookie

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("time",""+System.currentTimeMillis());
        resp.addCookie(cookie);
        resp.setStatus(200);
        resp.setContentType("text/html");
        resp.getWriter().write("<div>客户端存储cookie</div>");
    }

GetCookie

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookie = req.getCookies();
        for (Cookie c:cookie) {
            System.out.println(c.getName() + " = " + c.getValue());
        }
        resp.setContentType("text/html");
        resp.getWriter().write("<h3>服务器获取到cookie</h3>");
    }

先访问GetCookie,就会500,提示内部服务器错误,需要先访问SetCookie,然后再访问GetCookie,这样一来,访问GetCookie时,就会带有Cookie字段,从而访问成功。
还可以通过setMaxAge这个方法来设置Cookie的过期时间,时间一到,浏览器就会自动删除这个Cookie,就需要重新登陆了


Session:
虽然 Servlet 给我们提供了Cookie的一些操作,但是实际上,很少会直接操作Cookie,最主要的目的就是识别用户身份,直接使用Session也可以达到这样的效果。
在 HttpServletRequest 里有一个getSession方法,当参数为false时,直接返回,有就是有,没有就是没有(null)。参数为true时,没有Session就会创建一个Session。返回值为HttpSession
Session可以理解为一个会话,每一个用户访问服务器时,服务器都会给用户分配一个会话,服务器给多个用户服务,就存在多个会话,每个会话对象里都包含一些键值对属性,通过getAttribute()来获取某个键值对 setAttribute来设置键值对 removeAttribute移除键值对
判断当前会话是否存在的依据是SessionId,调用getSession()时,会先尝试在请求的Cookie中,有没有SessionId,如果没有SessionId,那么就会直接创建一个键值对,同时把这个SessionId通过Set-Cookie返回给浏览器,如果有SessionId,就查一下是否存在这个SessionId,如果不存在,还是要创建一个键值对,再通过Set-Cookie返回给浏览器,如果存在,直接通过SessionId查找对应的HttpSession对象即可
每个SessionId对应不同的HttpSession对象
也可以理解为在登陆机制中,只用Cookie还不够,还要用到Session
保存会话信息是在内存中,如果重启Tomcat,那么服务器端保存的会话信息就会丢失,如果不想丢失保存的会话信息,就可以把保存的会话信息放在磁盘上,如:保存在数据库里
服务器重启后,服务器端数据丢失,但客户端数据仍然在,所以请求中虽然会带有Cookie字段,但是服务器并不能识别或匹配,所以需要重新登陆一次。
在响应中,就可以找到SessionId、Path等信息在Set-Cookie中
一般来说,只有在login的时候,获取session时填写true,其它情况一般填写false

一个简单的登陆界面

登陆界面:

    <form action="login" method="post">
        <div>
            用户名<input type="text" name="username">
        </div>
        <div>
            密码<input type="password" name="password"></div>
        <div>
           <input type="submit" name="提交">
        </div>
    </form>    

登陆成功的界面(跳转至主页)

@WebServlet("/login")
public class Login extends HttpServlet {
    private String username = "lit";
    private String password = "lit";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.setContentType("text/html;charset = utf-8");
        if (username == null || "".equals(username) || password == null || "".equals(password)){
            resp.setStatus(403);
            resp.getWriter().write("<h3>登陆失败</h3>");
            return;
        }
        if (username.equals(this.username)&&password.equals(this.password)){
            resp.getWriter().write("<h3>登陆成功</h3>");
        }else {
            resp.setStatus(403);
            resp.getWriter().write("<h3>登陆失败</h3>");
            return;
        }
        HttpSession httpSession = req.getSession(true);
        httpSession.setAttribute("username",username);
        httpSession.setAttribute("time",System.currentTimeMillis());
        httpSession.setAttribute("visitCount",0);
        resp.setStatus(200);
        String html = String.format("<h3>登陆成功! 3s 之后跳转到主页</h3>");
        //这段代码意为:再设置的3000ms时间后执行function里的代码,借助JS代码里的定时器实现
        //此处也可以使用setInterval 也是JS定时器,只不过可以实现多个setTimeout的效果。(如:时间递减)
        html += "<script> setTimeout(function() { location.assign(\"index\"); }, 3000); </script>";
        resp.getWriter().write(html);
    }
}

主页:

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset = utf-8");
        // 确认当前用户是否已经登陆
        HttpSession session = req.getSession(false);
        //为false时,没有session就会返回null
        if (session == null){
            resp.sendRedirect("login.html");
            return;
        }
        String name = (String) session.getAttribute("username");
        Long time = (Long) session.getAttribute("time");
        int visitCount = (Integer) session.getAttribute("visitCount");
        visitCount += 1;
        session.setAttribute("visitCount",visitCount);

        String html = String.format("<div>欢迎 %s</div>",name);
        html += String.format("<div>上次访问时间: %d</div>",time);
        html += String.format("<div>访问次数:%s</div>",visitCount);

        resp.getWriter().write(html);
    }
}
上传文件

上传文件(浏览器选择一个本地的文件,把文件提交到服务器上)需要再页面上通过form表单做出一些支持,服务器也会通过Servlet做出支持
上传文件时的数据类型就需要做出修改Content-Type = multipart
上传文件后服务器要获取文件就要通过Part对象,要调用Part对象,就要使用@MultipartConfig注解
代码如下:
html

    <h3>上传文件</h3>
    <form action="uplode" method="post" enctype="multipart/form-data">
        <div>
            <input type="file" name="lit">
        </div>
        <div>
            <input type="submit" value="提交">
        </div>
    </form>

实现代码:

@MultipartConfig
@WebServlet("/uplode")
public class UpLodeServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //首先通过req.getPart()就能拿到一个Part对象,一个Part对象就能对应到一个上传的文件,一个http亲求中可以有多个Part对应多个文件
        Part part =req.getPart("lit");
        part.write("d:/lit.jpg");
        String name = part.getName();
        String fileName = part.getSubmittedFileName();
        String type = part.getContentType();
        long size = part.getSize();
        resp.setContentType("text/html;charset = utf-8");
        resp.getWriter().write("<div>上传成功</div>");
    }
}

这种方式只适合上传小文件
如果要上传1g左右的大文件,就需要考虑断点续传(再客户端把文件做出处理,用JS把文件切割成若干份。传到服务器后,服务器需要记录当前已经传了哪些份的数据。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值