day08-request&responseの代码练习

来源:互联网 发布:卫星地图软件 编辑:程序博客网 时间:2024/06/11 08:50

1:服务器端向客户端输出字节流例子

>
doGet方法中的关键代码

//1定义个将要输出到浏览器中的数据String str = "你好!Servlet";//2得到输出字节流OutputStream对象OutputStream os = response.getOutputStream();//3,通过设置输出字节的传输编码方式输出数据(防止中文乱码)os.write(str.getBytes("UTF-8");//4设置浏览器显示的编码方式os.write("<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>".getBytes();//5关闭流,这个没有必要写,因为Servlet引擎最后会检查自动关闭os.close()

2:Junit测试说明及URLEncoder类的方法使用举例

package com.itheima.test;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder;import junit.framework.Assert;import org.junit.Test;/** * 引入JUnit测试  :单元测试 ,是程序 员自己测试  *    被测试 的方法:  公有的  无返回值   无参数 *     *    规范:类的写法,一般以Test结尾 *          类中的方法      以test开头 *           *     断言: Assert类里面的方法 * @author wangli * */public class JTest {    @Test    public void testEncoder(){        //对于URL路径如何 编码         try {            String result  = URLEncoder.encode("美女.jpg","UTF-8");//编码            System.out.println(result);//%E7%BE%8E%E5%A5%B3.jpg        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }    }    @Test    public void testDecoder(){        try {            String result = URLDecoder.decode("%E7%BE%8E%E5%A5%B3.jpg","UTF-8");//还原            System.out.println(result);//美女.jpg        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }    }    @Test(timeout=1)   //单位:毫秒    public void testAssert(){        int a = 18;        //断言:判断结论        Assert.assertEquals(18, a);        for (int i = 0; i <100000; i++) {            a++;        }        System.out.println(a);//100018    }}

3:关于图片包含中文的文件下载

在Servlet中的doGet方法中的关键代码

package com.itheima.web.servlet;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URLEncoder;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 用于实现带有中文文件名的文件下载 * @author wangli * */public class DownloadServletDemo4 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException {    //1.得到这个文件 的绝对路径    String absolutePath = getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");//路径写法    //2.得到文件所对应的输入流    InputStream is = new FileInputStream(absolutePath);    //3.设置响应消息头    response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode("美女.jpg", "UTF-8"));    //4.得到一个用于向浏览器输出数据 的输出流    OutputStream os = response.getOutputStream();    //5.边读边写    int len=-1;    byte []buffer = new byte[1024];    while((len=is.read(buffer))!=-1){        os.write(buffer,0,len);    }    //6.关闭流    is.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException {    this.doGet(request, response);}//  getRealPath方法//  public java.lang.String getRealPath(java.lang.String path)//  Returns a String containing the real path for a given virtual path. For example, the path "/index.html" returns the absolute file path on the server's filesystem would be served by a request for "http://host/contextPath/index.html", where contextPath is the context path of this ServletContext.. //  The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators. This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive).////  Parameters://  path - a String specifying a virtual path//  Returns://  a String specifying the real path, or null if the translation cannot be performed

}

4:关于验证码的生成与输出

package com.itheima.web.servlet;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 验证码输出 * @author wangli * */public class AuthCodeServletDemo5 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        int height=25,width=120;        //1.得到一个图像缓冲区  BufferedImage        BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);        //2.得到一只画笔   Graphics        Graphics g = bimage.getGraphics();        //3.画矩形,填背景色   画干扰线条   画字符串        //3.1画矩形框时,可以先调画笔颜色        g.setColor(Color.BLUE);//先调画笔颜色        g.drawRect(0, 0 , width, height);        //3.2填充背景        g.setColor(Color.YELLOW);//调画笔颜色        g.fillRect(1,1, width-2, height-2);        //3.3画干扰线条        g.setColor(Color.GRAY);//调画笔颜色为灰色        Random random = new Random();//因为要画随机线条,引入随机数        for (int i = 0; i < 20; i++) {            //random.nextInt(width)因为要确定x坐标不能超范围            g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));        }        //3.4画随机字符串  先要控制字符颜色,及字体大小        g.setColor(Color.RED);        // Font.BOLD|Font.ITALIC 两种类型做迭加        g.setFont(new Font("黑体",Font.BOLD|Font.ITALIC,20));        for (int i = 0; i < 4; i++) {            g.drawString(random.nextInt(9)+"",20+(i*20), 20);        }        //4.将画好的缓冲区的图像写入到浏览器中        //4.1服务器要通过响应消息头,告知客户端,给它写的内容是一个一幅图片        response.setHeader("Content-Type", "image/jpeg");        //为了更好的让验证码,在客户端不要缓存,设置响应头,告诉客户端不要缓存        response.setHeader("Cache-Control", "no-cache");        response.setHeader("Pragma", "no-cache");        response.setHeader("Expires", "-1");        //4.2 写数据到浏览器   ImageIO        ImageIO.write(bimage, "jpg", response.getOutputStream());    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }}

5:关于Refresh的总结和URL的写法

Refresh:响应头,实现刷新效果,单位:秒
response.setHeader(“Refresh”,”2”);刷新到本页面
response.setHeader(“Refresh”,”2;URL=/day08_03_setHeader/index.jsp”);刷新到指定页面
总结URL的写法

  1. 给服务器用的,不需要写应用名

    1. getServletContext().getRealPath(“/WEB-INF/classes/1.jpg”);
    2. getServletContext().getRequestDispatcher(“/servlet/ServletDemo2”);
  2. 给浏览器用的,要写应用名

  3. URL:

    6:设置过期时间

    doGet方法中的关键代码

    response.setDateHeader("Expires",System.currentTimeMillis()+1000*60*60);//缓存1小时

    7:Redirect重定向

    原理:

    302+Location

    特点:

    客户端发出2次请求地址栏改变request域中的数据不能共享response。sendRedirect("重定向定制");

    举例:

    response.sendRedirect("/"/day08_03_setHeader/servlet/DateExpiresDemo7");//重定向  它发出2次请求,都是客户端发出的请求

    8:获取请求消息头例子

    package com.itheima.web.servlet;import java.io.IOException;import java.util.Enumeration;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 获取请求消息头 * @author wangli * */public class GetHeaderDemo1 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //1.获取一个请求头所对应的值        testGetHeader(request);        //2.获取一个请求头所对应的一组值        testGetHeaders(request);        //3.获取所有的请求消息头        testAllHeaders(request);    }    //获取所有的请求消息头    @SuppressWarnings("unchecked")    private void testAllHeaders(HttpServletRequest request) {        Enumeration<String> enumsss = request.getHeaderNames();//得到客户端发过来的所有请求消息头        System.out.println("得到客户端发过来的所有请求消息头");        while(enumsss.hasMoreElements()){            String headerName = enumsss.nextElement();//取出一个请求头            String headerValue = request.getHeader(headerName);//根据指定请求头名字,取出所对应的value            System.out.println(headerName +":"+headerValue);        }    }    //获取一个请求头所对应的一组值    @SuppressWarnings({ "unchecked", "unused" })    private void testGetHeaders(HttpServletRequest request) {        System.out.println("获取一个请求头所对应的一组值");        Enumeration<String> client = request.getHeaders("Accept-Encoding");//得到的是客户端支持的数据压缩方式 是一组值        while(client.hasMoreElements()){            String headerValue = client.nextElement();            System.out.println(headerValue);        }    }    //获取一个请求头所对应的值    @SuppressWarnings("unused")    private void testGetHeader(HttpServletRequest request) {        String client = request.getHeader("Accept-Encoding");//得到的是客户端支持的数据压缩方式  Accept-Encoding: gzip;deflate        System.out.println("获取一个请求头所对应的值");        System.out.println("头信息Accept-Encoding的值是:" + client);        if(client.contains("gzip")){            System.out.println("支持Gzip压缩");        }else{            System.out.println("不支持Gzip压缩");        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }}

    9:获取客户端的基本信息

    package com.itheima.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 用于获取客户端的基本信息 * @author wangli * */public class RequestBasicMethodsDemo2 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        String clientIP =  request.getRemoteAddr();//得到客户端的ip        System.out.println("ip="+clientIP);//ip=127.0.0.1        String uri = request.getRequestURI();//得到客户端所请求的资源地址:只包含资源地址        System.out.println("uri="+uri);//uri=/day08_05_requestbasic/servlet/RequestBasicMethodsDemo2        String url = request.getRequestURL().toString();//代表获取客户端请求的地址:协议+主机地址+端口号+资源地址        System.out.println("url="+url);//url=http://localhost:8080/day08_05_requestbasic/servlet/RequestBasicMethodsDemo2        //有可能应用名与工程名不同名        String applicationName = request.getContextPath();//它能动态获取应用名        System.out.println("应用名="+applicationName);//应用名=/day08_05_requestbasic        int port = request.getRemotePort();//得到客户端本次请求时,所使用的端口号        System.out.println("端口号="+port);//端口号=53235      端口号每次请求会不一样    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }}

    10:从前台注册页面到后台数据封装的常见五个方法

    1. 首先建立Bean对象

    /** * Serializable 是专门用于实现序列化的 *      实现了这个接口,意味着这个类是可以被序列化 *      实现这个接口,意味着可以在网络上直接传输一个对象 *  * 什么是序列化?它支持一次性将一个对象存入到文件中 *  *  * JavaBean规范 *  1.是一个公有类 *  2.提供私有字段  *  3对于这些私有字段 ,提供 getter 与setter *  4.提供一个公有的无参构造 *  5.一般 实现Serializable接口 *   *   *  是一个程序员的基本素质:      约定优于编码 * @author wangli * */

        package com.itheima.domain;    import java.io.Serializable;    import java.util.Arrays;    public class User implements Serializable {        private String username;        private String password [];        public User() {            super();        }        public User(String username, String[] password) {            super();            this.username = username;            this.password = password;        }        @Override        public String toString() {            return "User [用户名=" + username + ", 密码="                    + Arrays.toString(password) + "]";        }        public String getUsername() {            return username;        }        public void setUsername(String username) {            this.username = username;        }        public String[] getPassword() {            return password;        }        public void setPassword(String[] password) {            this.password = password;        }    }



    后台处理代码:
    package com.itheima.web.servlet;

    import java.beans.PropertyDescriptor;import java.io.IOException;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Enumeration;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.beanutils.BeanUtils;import com.itheima.domain.User;/** * 用于接收来自login.html发过来的请求数据 * <input type="text" name="username" > * <input type="password" name="password" > * <input type="password" name="password" > *  * 并封装到对象中 * @author wangli * */public class UserRegistServlet01 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        test1(request);//封装数据,手动封装        test2(request);//反射封装参数        test3(request);//内省实现参数封装        test4(request);//BeanUtils封装数据        test5(request);//BeanUtils封装数据    }    private void test5(HttpServletRequest request) {        User user = new User();//封装前        System.out.println("封装前:"+user);        //封装过程            //引入了一个新知识点  BeanUtils            try {                BeanUtils.populate(user, request.getParameterMap());            } catch (Exception e) {                e.printStackTrace();            }        System.out.println("封装后:"+user);    }    //开发中不用    private void test4(HttpServletRequest request) {        User user = new User();//封装前        System.out.println("封装前:"+user);        //封装过程        //1.服务器接收客户端发过来请求数据 ,如果 页面上请求很多时,可以用getParameterMap();得到所有的请求参数名及参数值        Map<String,Object [] >map = request.getParameterMap();//key:是封装数名的,一定是String     Value:  因为一个参数名可以对应多个值request.getParameterValues(paramName);         for(Map.Entry<String,Object[]> entry:map.entrySet()){            String paramName = entry.getKey();//取参数名            Object []objs = entry.getValue();//取值            //引入了一个新知识点  BeanUtils            try {                BeanUtils.setProperty(user, paramName, objs);            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println("封装后:"+user);    }    /**     * 内省封装数据     * 开发中不用     * @param request     */    private void test3(HttpServletRequest request) {        User user = new User();//封装前        System.out.println("封装前:"+user);        //封装过程        //1.服务器接收客户端发过来请求数据 ,如果 页面上请求很多时,可以用getParameterNames();得到所有的请求参数名        Enumeration<String> enumsss  = request.getParameterNames();        while(enumsss.hasMoreElements()){            String paramName = enumsss.nextElement();//取出其中的一个参数名name="username"    <input type="text" name="username" >            String []paramValues = request.getParameterValues(paramName);//得到这个参数所对应的一组值            //封装到对象user中  ,此时的paramName 一定要与User的属性保持一致            //内省            try {                PropertyDescriptor pd =new PropertyDescriptor(paramName, user.getClass());//属性描述器 第一个参数是指哪个属性   第二个参数是哪个Class                Method method = pd.getWriteMethod();//通过属性描述器,得到setter方法                if(paramValues!=null && paramValues.length>1){                    method.invoke(user, (Object)paramValues);//参考反射Main方法,   setUsername(String []username)                }else {                    method.invoke(user, paramValues[0]);//只有一个参数,不要包装                }            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println("封装后:"+user);    }    /**     * 反射封装参数     *      开发中不提倡这样用     * @param request     */    private void test2(HttpServletRequest request) {        User user = new User();//封装前        System.out.println("封装前:"+user);        //封装过程        //1.服务器接收客户端发过来请求数据 ,如果 页面上请求很多时,可以用getParameterNames();得到所有的请求参数名        Enumeration<String> enumsss  = request.getParameterNames();        while(enumsss.hasMoreElements()){            String paramName = enumsss.nextElement();//取出其中的一个参数名name="username"    <input type="text" name="username" >            String []paramValues = request.getParameterValues(paramName);//得到这个参数所对应的一组值            //封装到对象user中  ,此时的paramName 一定要与User的属性保持一致            Class clzz = user.getClass();//反射            try {                //用反射得到user对象的一个paramName的属性                Field f = clzz.getDeclaredField(paramName);//得到了一个私有属性                f.setAccessible(true);//爆力反射  这样就可以使得一个私有属性,在另外一个类中可以被 使用                if(paramValues!=null && paramValues.length>1){                    f.set(user, (Object)paramValues);//参考反射Main方法,   setUsername(String []username)                }else {                    f.set(user, paramValues[0]);//只有一个参数,不要包装                }            } catch (Exception e) {                e.printStackTrace();            }        }        System.out.println("封装后:"+user);    }    //封装数据,手动封装    private void test1(HttpServletRequest request) {        //1.服务器接收客户端发过来请求数据        String username = request.getParameter("username");//username来自于表单<input type="text" name="username" >name的名字        String password []= request.getParameterValues("password");//得到一组值        User user = new User();//封装前        System.out.println("封装前:"+user);        //封装过程        user.setUsername(username);        user.setPassword(password);        System.out.println("封装后:"+user);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }}



    后台接收数据解决乱码问题
    package com.itheima.web.servlet;

    import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.beanutils.BeanUtils;import com.itheima.domain.User;/** * 接收用户注册信息并封装,可以解决乱码 *     客户端发过来的请求数据的方式 :  get/post *      服务器端处理乱码也要分两种情况: *              1.post方式 下乱码如何处理? *                      request.setCharacterEncoding("UTF-8"); *  *              2.get方式 下乱码如何处理?用get请求向服务器发送数据默认采用iso-88549-1    UTF-8----iso-8859-1--------------->发给服务器 *                                          ---------->String (要还原   iso-8859-1)[01010101010111111111]------------>UTF-8 *                       * @author wangli * */public class UserRegistServlet02 extends HttpServlet {    //处理get 请求    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {                String username = request.getParameter("username");                //3.处理乱码                    //3.1还原为iso-8859-1                        byte [] encode = username.getBytes("iso-8859-1");                    //3.2用UTF-8编码重构                        username = new String(encode,"UTF-8");                System.out.println(username);                //3.输出数据                response.setContentType("text/html;charset=UTF-8");                response.getWriter().write("GET<br>");                response.getWriter().write(username);    }    //处理post请求    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //1.设置服务器接收post 请求发过来的数据的编码        request.setCharacterEncoding("UTF-8");//只能处理post提交数据时的乱码问题        //2.封装数据        User user = new User();        try {            BeanUtils.populate(user, request.getParameterMap());        } catch (Exception e) {            e.printStackTrace();        }        //3.输出数据        response.setContentType("text/html;charset=UTF-8");        response.getWriter().write(user.toString());    }}



    前台注册界面的代码如下:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>login.html</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>   <table width="100%" border="0" cellspacing="0" cellpadding="4">    <tr>         <td bgcolor="#000099">             <table width="100%" border="0" cellspacing="0" cellpadding="4">                <tr>                     <td bgcolor="#FFFFFF">&nbsp;<b>*</b>&nbsp;</td>                        <td width="100%"><font color="#CCCCCC">&nbsp; <font color="#FFFFFF">注册</font></font></td>                </tr>            </table></td>    </tr>    <tr>         <td width="100%" bgcolor="#EAEAEA" colspan="2">             <!-- action 的写法:   request.getContextPath()不要写它-->            <!-- <form  method="post" action="/day08_06_getParameter/servlet/UserRegisterServlet02"><p> -->            <!-- get提交数据到服务器 -->            <form  method="get" action="/day08_06_getParameter/servlet/UserRegistServlet2"><p>                 <label for="textfield">用户名</label>                <br>                <!-- name属性的名字,不要随意定义,要与实体User保持一致 -->                <input type="text" name="username" >                </p>                <p>                <label for="textfield2">密码</label>                <br>                <input type="password" name="password" >                </p>                <p>                <label for="textfield2">确认密码</label>                <br>                <input type="password" name="password" >                </p>                <p>                 <input type="submit"  value="注册">                </p>                <p>&nbsp; </p>                </form>        </td>  </tr></table>  </body></html>

    11:转发,包含,重定向

    DispatcherDemo1.java

    >
    //获得转发器RequestDispatcher,如果用request对象获得的话,其中地址既可以写相对路径,也可以写绝对路径如果用ServletContext()获得的话,只能写相对路径
    RequestDispatcher rd = request.getRequestDispatcher(“/servlet/DispatcherDemo2”);
    ServletContext().getRequestDispatcher(“/servlet/DispatcherDemo2”);
    //包含
    rd.include(request.response);//在实现包含时,会先将被包含进来的页面的头信息清空
    //转发
    rd.forward(request,response);//在转发钱,先要将response中的数据全部清空
    //重定向
    response.sendRedirect(request.getContextPath()+”/servlet/DispatcherDemo2”);

0 0
原创粉丝点击