servlet的使用——response和request

在Servlet中可以使用的内置对象主要有:request、response、application(应用程序)、session(会话)、out(PrintWriter)。

一、response对象

1.1 ServletResponse简介

定义辅助 servlet 将响应发送到客户端的对象。servlet 容器创建 ServletResponse 对象,并将它作为参数传递给 servlet 的 service 方法。 要发送 MIME 正文响应中的二进制数据,请使用 getOutputStream 返回的 ServletOutputStream。要发送字符数据,请使用 getWriter 返回的 PrintWriter 对象。

1.2 HttpServletResponse介绍

扩展 ServletResponse 接口以提供特定于 HTTP 的发送响应功能。例如,该接口拥有访问 HTTP 头和 cookie 的方法。 客户端向服务器发起的都是HTTP协议操作,所以我们大部分使用HttpServletResponse对象作为直接操作对象!

1.3 HttpServletResponse 常用API介绍

方法名称作用
setStatus(int code)设置响应状态码:200 成功 302 临时重定向 304 处理缓存 404 Not Found没有找到资源,500 服务器错误
setHeader(name,value)设置响应信息头
setCharacterEncoding(String);设置编码格式
setContentType(String)设置返回数据mimetype
getWriter()获取字符输出流
getOutputStream()获取字节输出流
getServletContext()一个servlet可以使用getServletcontext()方法得到了web应用中的Servletcontext,从而使用Servletcontext接口的一些方法,比如getRealPath获取实际路径,可以用于获取web下的文件

1.4 案例一——预览和下载图片(两种方式)

预览和下载,只是差一个方法的问题,但是不能共存

//如果将图片放到了web文件夹下,则需要通过getServletContext()方法获取
@WebServlet(name = "DownServlet", value = "/downservlet")
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用application获取web下的图片
        //一个servlet可以使用getServletcontext()方法得到了web应用中的Servletcontext,从而使用Servletcontext接口的一些方法
        ServletContext servletContext = this.getServletContext();
        //通过servletContext使用接口中方法,getRealPath获取实际路径
        String realPath = servletContext.getRealPath("img/蜜獾.jpg");

        //设置响应头,content-disposition内容如何处理,如何配置,保存,进行下载处理,与显示是分开独立的,不能既显示又下载,这里要设置编码,否则无法正常显示图片
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("img/蜜獾.jpg", "utf-8"));

        FileInputStream fis = new FileInputStream(realPath);
        ServletOutputStream os = response.getOutputStream();

        byte[] bytes = new byte[1024 * 8];
        int len = -1;
        while ((len = fis.read(bytes)) != -1) {
            os.write(bytes, 0, len);
            os.flush();
        }

        fis.close();
        os.close();
        System.out.println("执行完毕");
    }

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

//如果图片在src文件夹下,则使用类加载器获取
@WebServlet(name = "DownLoadServlet", value = "/downloadservlet")
public class DownLoadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        InputStream is = DownLoadServlet.class.getClassLoader().getResourceAsStream("img/蜜獾.jpg");
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("img/蜜獾.jpg", "utf-8"));
        ServletOutputStream os = response.getOutputStream();
        byte[] buf = new byte[1024 * 8];
        int len = -1;
        while ((len = is.read(buf)) != -1) {
            os.write(buf, 0, len);
            os.flush();
        }
        is.close();
        os.close();
    }

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

1.5 案例二——页面中添加验证码

项目中要导入jar包:validatecode.jar
创建并返回验证码的servlet
注:验证码就是一个图片

验证码servlet类

@WebServlet(name = "ValidatecodeServlet", value = "/vs")
public class ValidatecodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建验证码
        //宽度、高度、个数、干扰线个数
        ValidateCode validateCode = new ValidateCode(120,30,4,25);
        String code = validateCode.getCode();
        System.out.println("验证码" + code);//可以获取验证码值在控制台打印,也可以不用打印
        //验证码图片给到浏览器
        validateCode.write(response.getOutputStream());
    }

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

注册类,使用验证码【重点】

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
    <h2>用户注册</h2>
    <form action="registservlet" method="post" enctype="application/x-www-form-urlencoded">
        用户名<input type="text" name="username"/><br/>
        密码<input type="password" name="password"/><br/>
        确认密码<input type="password" name="repassword"/><br/>
        邮箱<input type="email" name="email"/><br/>
        验证码:<img id="codeing" src="/0831web1/vs" onclick="changeing()"/>
        <!--必须有href,否则不能点击,里面为空,表示刷新本页面-->
        <!--onclick中内容为方法,下面可知返回为false,再来一个return false将结果给a标签,要求不刷新本页面-->
        <a href="" onclick="return changeing()">看不清</a><br/>
        <input type="submit" value="提交"/><br/>
    </form>
<script type="text/javascript">
    function changeing() {
        var codeing = document.getElementById("codeing");
        //?及?号后面的代码不影响路径,不影响查找到vs,这里目的是给vs一个路径,让vs以为页面变化了,从而刷新验证码,但其实并未跳转其他页面
        codeing.src="/0831web1/vs?n=" + Math.random();
        return false;   //不允许跳转页面,将值返回给a标签,保证不刷新本页面
    }
</script>
</body>
</html>

二、request对象

2.1 ServletRequest介绍

定义将客户端请求信息提供给某个 servlet 的对象。servlet 容器创建ServletRequest 对象,并将该对象作为参数传递给该 servlet 的service方法

2.2 HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
同响应相同,客户端请求协议都是基于HTTP所以我们选用HttpServletRequest来操作用户发送过来的请求的数据!

2.3 HttpServletRequest常用API

URL :Uniform Resource Location (统一资源定位符) 网址,是一个地址
URI :Uniform Resource Identifier (统一资源标识符) URI包含URL,是一个名字

方法的使用
getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名
getMethod得到客户机请求方式

//获取请求头信息
getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法

//获取请求正文参数
getParameter(name)方法
getParameterValues(String name)方法,返回字符串数组,用于多选框
getParameterNames方法
getParameterMap方法 //做框架用,非常实用
getInputStream方法 获取输入流
setAttribute方法,键值对存储
getAttribute方法,根据键获取值
removeAttribute方法, 根据键删除

@WebServlet(name = "RequestServlet",value = "/requestservlet")
public class RequestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取request对象信息
        System.out.println("URL:" + request.getRequestURL());
        System.out.println("URI:" + request.getRequestURI());

        //查询的是在地址栏中get获取的?号后面的字符串内容
        System.out.println("查询字符串getQueryString:" + request.getQueryString());

        System.out.println("远端IP地址getRemoteAddr:" + request.getRemoteAddr());
        System.out.println("远端主机getRemoteHost:" + request.getRemoteHost());
        System.out.println("远端端口号getRemotePort:" + request.getRemotePort());
        System.out.println("本地IP地址getLocalAddr:" + request.getLocalAddr());
        System.out.println("本地端口号getLocalPort:" + request.getLocalPort());

        System.out.println("------请求头-------");
        String accept = request.getHeader("accept");
        System.out.println(accept);

        System.out.println("-----getHeaderName请求头属性和值------");
        //是一个枚举选择器
        Enumeration<String> headerNames = request.getHeaderNames();
        //循环遍历
        while (headerNames.hasMoreElements()) {
            String headname = headerNames.nextElement();
            //通过请求头名称获取值
            System.out.println(headname + "==" + request.getHeader(headname));
        }

        System.out.println("attribute集合的使用");
        //该集合必须先放入数据,然后才能获取数据
        request.setAttribute("username", "Jack");
        request.setAttribute("age", "20");
        Object username = request.getAttribute("username");
        Object age = request.getAttribute("age");
        System.out.println(username + "...." + age);
        request.removeAttribute("username");
    }

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

//打印结果:
URL:http://localhost:8080/0831web1/requestservlet
URI:/0831web1/requestservlet
查询字符串getQueryString:null
远端IP地址getRemoteAddr:0:0:0:0:0:0:0:1
远端主机getRemoteHost:0:0:0:0:0:0:0:1
远端端口号getRemotePort:62496
本地IP地址getLocalAddr:0:0:0:0:0:0:0:1
本地端口号getLocalPort:8080
------请求头-------
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
-----getHeaderName请求头属性和值------
host==localhost:8080
connection==keep-alive
upgrade-insecure-requests==1
user-agent==Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36
sec-fetch-mode==navigate
accept==text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
sec-fetch-site==none
accept-encoding==gzip, deflate, br
accept-language==zh-CN,zh;q=0.9
cookie==Idea-b2e7a278=580841ca-1fcd-4ccf-ad1b-446395a835aa; username=??????
attribute集合的使用
Jack....20

三、案例——封装请求参数

将从前端页面获取的数据封装到实体类上,创建一个对应的实体类,实体类变量命名和变量类型都有相应的要求,要求变量名跟提交参数的key相同,变量跟参数类型相同!

User类

只列举属性,略去set和get方法,以及toStirng方法等

public class User {
    private Integer id;
    private String username;
    private String password;
    private String gender;
    private String[] hobby;

    public User() {
    }

    public User(Integer id, String username, String password, String gender, String[] hobby) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.gender = gender;
        this.hobby = hobby;
    }
}
html文件,info信息的提交
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户信息</title>
</head>
<body>
    <h2>用户信息</h2>
    <form action="infoservlet" method="post" enctype="application/x-www-form-urlencoded">
        学号<input type="text" name="id"><br/>
        用户名<input type="text" name="username"/><br/>
        密码<input type="password" name="password"/><br/>
        性别<input type="radio" name="gender" value="man"/><input type="radio" name="gender" value="woman"/><br/>
        爱好<input type="checkbox" name="hobby" value="book"/>看书
        <input type="checkbox" name="hobby" value="javaBook"/>看java书
        <input type="checkbox" name="hobby" value="movie"/>看电影
        <input type="checkbox" name="hobby" value="music"/>听音乐<br/>
        <input type="submit" value="提交">
    </form>
</body>
</html>
infoServlet获取前端信息的方式

一共有三种方式:getParameter、反射和内省来封装、BeanUtils

@WebServlet(name = "infoServlet", value = "/infoservlet")
public class infoServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        /*一、使用getParameter获取,此方法是先获取再封装,很麻烦*/
        Integer id = Integer.valueOf(request.getParameter("id"));
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");
        String[] hobby = request.getParameterValues("hobby");
        User user = new User(id,username, password, gender, hobby);
        System.out.println(user.toString());

        /*二、反射和内省来封装,是BeanUtils的原理,这里注意数据类型的处理以及内省机制*/
        User user = new User();
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            String key = entry.getKey();
            try {
                PropertyDescriptor pd = new PropertyDescriptor(key, User.class);
                if (pd != null) {
                    String[] value = entry.getValue();
                    Method writeMethod = pd.getWriteMethod();

                    //值会重复不唯一,所以entry.getValue()获取的是数组
                    //有的key对应的值是唯一的,比如username,所以只需要value[0]赋值即可
                    //有的key对应的值是很多的,比如hobby,需要将地址给hobby,自然不能用value[0]
                    //所以需要判断
                    if(pd.getPropertyType().isArray()) {
                        //同样,entry.getValue()获取的类型都是String,但是对应的hobby数组类型不一定是String,需要转型
                        writeMethod.invoke(user, (Object) value);
                    } else {
                        //需要判断是否为Integer类型,否则需要进行转换
                        if (pd.getPropertyType() == Integer.class) {
                            writeMethod.invoke(user, Integer.parseInt(value[0]));
                        } else {
                            writeMethod.invoke(user, value[0]);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(user.toString());

        /*三、使用Apache BeanUtils进行快速映射*/
        User user = new User();
        try {
            BeanUtils.populate(user, request.getParameterMap());
            System.out.println(user.toString());
            //其他方法
            //复制
            User user2 = new User();
            BeanUtils.copyProperties(user2, user);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

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

第三种方式,必须导入jar包:beanutils对应jar包、logging日志、commons-collections-3.2.1.jar。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值