requeset&&response

本文详细介绍了Java Web开发中的编码问题解决方案,包括如何设置request和response的编码以避免乱码,以及如何处理请求转发、请求重定向和请求包含等核心概念。
1、编码问题

这里讲的都是HttpServletRequest和respoHttpServletResponsese,他们的父类ServletRequets和ServletResponsese也有很多方法,参看相应的api,这里只讲基础。
在使用java写web程序的时候,编码问题需要注意。
在服务器传进来的request和response当中可以设置编码,来告诉服务器浏览器使用什么编码方式来编码,从而避免乱码问题。

  1. response:回应从发送数据出去,需要告诉服务器和浏览器使用什么编码方式
//告诉服务器应用使用UTF-8解析文本
response.setCharacterEncoding("UTF-8");
//告诉客户端要使用什么编码
response.setHeader("content-type", "text/html;charset=UTF-8");

//告诉服务器应用使用UTF-8解析文本,告诉客户端要使用什么编码
response.setContentType("text/html; charset=UTF-8");
  1. request:请求,从浏览器获取数据,需要知道浏览器的编码方式从而对获取到的数据进行解码。如果不设置,服务器会使用iso-8859-1的编码方式进行解码,但是从浏览器获取的数据一般来说都是使用的UTF-8
//告诉服务器使用这个编码方式进行解析
request.setCharacterEncoding("UTF-8");

这里写图片描述

对于response和request来说,无非就是获取和填写响应头,和响应正文以及请求行。

//请求行
getMethod(); //获得请求方式
getRequestURL();//返回客户端发出请求时的完整URL。
getRequestURI(); //返回请求行中的资源名部分。
getContextPath();// 当前应用的虚拟目录 /app
getQueryString() ; //返回请求行中的参数部分。

获取请求消息头

  • getHeader(String name) ;//根据头名称得到头信息值利用”User-Agent”
  • Enumeration getHeaderNames() ; //得到所有头信息name例如”Content-language”
  • Enumeration getHeaders(String name) ;//根据头名称得到相同名称头信息值
private void test2(HttpServletRequest request) {
    //获得所有请求消息头的name
    Enumeration names = request.getHeaderNames();

    while(names.hasMoreElements()){
        String e = (String) names.nextElement();
        System.out.println(e+":"+request.getHeader(e));
    }
}

请求正文

  • getParameter(name) 根据表单中name属性的名,获取value属性的值方法
  • getParameterValues(String name)专业为复选框取取提供的方法
  • getParameterNames() 得到表单提交的所有name的方法
  • getParameterMap 到表单提交的所有值的方法 //做框架用,非常实用
  • getInputStream 以字节流的方式得到所有表单数据

其中getParameterMap ()这个方法用于框架将获取到的数据封装起来很方便实用
使用getParameterNames()方法

//这一句需要添加上
request.setCharacterEncoding("UTF-8");//只能解决post方式的乱码,get的参看上面
private void test2(HttpServletRequest request) {
    //获取所有的表单name的名子
    Enumeration names = request.getParameterNames();
    while(names.hasMoreElements()){
        String name = (String) names.nextElement();//得到每一个name名
        String[] values = request.getParameterValues(name);//根据name名,得到value值
        for (int i = 0;values!=null && i < values.length; i++) {
            System.out.println(name+"\t"+values[i]);
        }
    }
}

使用实体进行封装,首先创建一个实体

public class User {
    //这里需要设置setter和getter方法,这样才能使用反射还是自省?
    private String userName;
    private String pwd;
    private String sex;
    private String[] hobby;
    private String city;
}

private void test3(HttpServletRequest request) {
    try {
        User u = new User();
        System.out.println("封装数据前:"+u);//都为空
        //获取表单数据
        Map<String,String[]> map = request.getParameterMap();

        for (Map.Entry<String, String[]> m : map.entrySet()) {
            String name = m.getKey();
            String[] value = m.getValue();
            //创建一属性描述器,自省
            PropertyDescriptor pd = new PropertyDescriptor(name, User.class);
            //得到setter属性
            Method setter = pd.getWriteMethod();

            if(value.length==1){
                setter.invoke(u, value[0]);//给一个值的变量赋值
            }else{
                setter.invoke(u, (Object)value);//相关于给复选框赋值
            }
        }
        System.out.println("封装数据后:"+u);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

使用框架,阿帕奇提供的BeanUtils

import org.apache.commons.beanutils.BeanUtils;
private void test4(HttpServletRequest request) {
    try {
        User u = new User();
        System.out.println("封装数据前:"+u);

        BeanUtils.populate(u, request.getParameterMap());

        System.out.println("封装数据后:"+u);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

以上两种方法都必须在User当中设置get和set方法,这样才可以对字段进行赋值,



与操作非表单数据相关的方法(request也是一个域对象),也就可以通过request对象携带数据到其他servlet当中

  • void setAttribute(String name, Object value);
  • Object getAttribute(String name);
  • Void removeAttribute(String name);
//将非表单的数据添加到request的域中
request.setAttribute("s", str);
request.getRequestDispatcher("/servlet/demoX").forward(request, response);

在demoX当中接受数据

String s = (String) request.getAttribute("s");

2、请求转发和请求重定向

请求转发和请求从定最大的区别是请求转发是在服务器上进行的,请求重定向是在浏览器上进行的。由这个最大的区别可以知道他的一些其他的区别。

  1. 请求转发可以携带数据,尔请求重定向不行
  2. 请求转发只能转发到同一个应用当中的其他servlet当中。请求重定向可以转发到其他链接当中。因为是在浏览器上进行的。同时,请求转发其他的servlet完成后会返回到当前的这个servlet当中。
  3. 请求转发客户端只发送意思请求,请求重定向是两次。
  4. 请求转发浏览器地址栏不会变化,请求重定向会发生变化

    请求转发的代码实现:

//将请求转发到demo6中
request.getRequestDispatcher("/servlet/demo6").forward(request, response);

请求重定向

//way 1
//需要从当前引用的更目录开始写地址,因为浏览器只知道当前服务器的地址,不知道应用的地址
response.sendRedirect(request.getContextPath()+"/servlet/demo6");

//way 2 在header当中添加location实现跳转
response.setStatus(302);
//告诉浏览器要去访问哪个URL
response.setHeader("location", "/day09_00_HttpServletResponse/servlet/demo8");*/

请求包含,一个请求包换另一个请求,与请求转发相似

//请求包含
request.getRequestDispatcher("/servlet/demo6").include(request, response);
response.setIntHeader("refresh", 1);//设置1秒钟刷新一次

//告诉客户端不使用缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setIntHeader("expires", 0);

//获取输入输出的字节流
ServletOut(in)putStream sos = response.getOut(in)putStream();
getWrite();//字符输出流
getRead();字符流输入
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值