您的位置:首页 > 理论基础 > 计算机网络

HttpServlet

2015-09-07 22:42 681 查看
HttpServlet详解

一、请求和响应对象概述(**)

HTTP协议包含请求和响应部分。

HttpServletRequest就代表着请求部分

HttpServletResponse就代表着响应部分

学好的关键:HTTP协议。

二、HttpServletResponse详解(*****)

2.1输出中文数据(字符流与字节流)

字节流:

// 以字节流默认的本地GBK编码输出中文数据,没有乱码

String s = "幸福是神马 ";

ServletOutputStream out = response.getOutputStream();

out.write(s.getBytes());

// 以字节流用UTF-8编码输出中文数据,有乱码

out.write("中文".getBytes("UTF-8"));

解决办法:

方式一:更改浏览器的查看编码(不可取)

注: 方式二、三、四都是一样的,即通知浏览器,使用的码表

方式二:response.setHeader("Content-Type", "text/html;charset=UTF-8");

方式三:response.getOutputStream().write("<meta http-equiv='Content-Type'

content='text/html;charset=UTF-8'>".getBytes("UTF-8"));

*方式四:response.setContentType("text/html;charset=UTF-8");

字符流:

Servlet中的字符流默认查ISO-8859-1(SUN的Servlet规范要求的)

更改这个默认的编码的方式: response.setCharacterEncoding("UTF-8");

//不要忘记通知浏览器的编码

response.setCharacterEncoding("UTF-8");

方式1:response.setHeader("Content-Type", "text/html;charset=UTF-8");

方式2:response.setContentType("text/html;chatset=UTF-8");

PrintWriter out = response.getWriter();

out.write(s);

在字符流输出中文数据时:response.setContentType("text/html;charset=UTF-8");

有两个作用:通知字符流以UTF-8编码输出

通知客户端以UTF-8解码显示

注: 输出整数,转换成字符串形式,即可,比如98无论查哪个码表都是b

2.2控制不要缓存

response.setHeader("Expires", "-1");

response.setHeader("Cache-Control", "no-cache");

response.setHeader("Pragma", "no-cache");

2.3控制缓存时间

// 缓存1小时

response.setDateHeader("Expires", System.currentTimeMillis()+60*60*1000);

2.4动态生成随机验证码图片(见例子Demo)

2.5定时刷新

// 定时刷新自身页面

方式1: response.setHeader("Refresh", "1");

方式2: response.setIntHeader("Refresh", 1);

// 定时刷新到其他页面

response.setHeader("Refresh", "3;URL=/day06/index.html");

2.6文件下载(中文文件名的文件下载)(见例子Demo)

2.7HttpServletResponse细节:

字节流和字符流不能同时使用,互斥的。

通过字符流或字节流输出的数据并不是直接打给浏览器的。而是把数据写到response对象的缓存中的。

服务器从缓存中取出数据,按照HTTP协议的响应格式输出给浏览器。

如果你调用的response的输出流没有主动关闭,服务器会替你关的。


三、HttpServletRequest详解 (*****)

代表着客户端的请求。要客户的信息只要找这个对象即可,该对象由容器创建。

学习关键:时刻记住HTTP协议的请求部分的具体内容。

3.1常用简单方法

**********************************************************************************************

// 获取URL: 协议 + 主机 + 端口

// 资源的地址:http://localhost:8080/day07/servlet/RequestDemo1

String url = request.getRequestURL().toString();

// 获取URI: 请求的资源地址: /day07/servlet/RequestDemo1

String uri = request.getRequestURI();

// 获取get方式的请求参数字符串:

// /day07/servlet/RequestDemo1?username=asd&password=123

// 得到: username=asd&password=123 注: 若为post方式,则为null

String qs = request.getQueryString();

// 获得主机地址

String remoteAddr = request.getRemoteAddr();

// 获取客户机的端口号 注: 不是服务器使用的端口号,客户机使用的端口号是随机的(>1024)

int remotePort = request.getRemotePort();

// 获取请求方式 注: 根据浏览器的不同,返回值的字母大小写不同,若要判断,须忽略大小写

String method = request.getMethod();

**********************************************************************************************

3.2获取请求消息头

**********************************************************************************************

// 获取指定的头的值: 如头:Accept-Encoding

String value = request.getHeader("Accept-Encoding");

// 获取重名的头的值: 如头:User-Agent

Enumeration e = request.getHeaders("User-Agent");

while(e.hasMoreElements()){

String value = (String) e.nextElement();

out.write(value);

}

// 获取所有的请求头名和头值 注: 即模拟Httpwatch中Stream中的请求部分

Enumeration e = request.getHeaderNames();

while(e.hasMoreElements()){

String headerName = (String) e.nextElement();

String headerValue = request.getHeader(headerName);

out.write(headerName + "\t" + headerValue + "<br/>");

}

**********************************************************************************************

3.3获取请求参数(内省)(注: 请求正文即请求参数 见httpwatch)

**********************************************************************************************

// 获取指定单一参数的值 : 注: 不能获取重名的参数的值,只显示第一次的值

String username = request.getParameter("username");

// 获取指定重名参数的值

String usernames[] = request.getParameterValues("username");

for(String s : usernames)

System.out.println(s);

// 获取所有的参数和取值

Enumeration e = request.getParameterNames(); // 获取所有的请求参数名

while(e.hasMoreElements()){

String paramName = (String) e.nextElement();

String values[] = request.getParameterValues(paramName);

System.out.println(paramName + "----" + Arrays.asList(values));

}

// BeanUtils内省框架获取请求参数,封装到JavaBean中

User user = new User();

System.out.println("封装前:" + user);

try {

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

} catch (Exception e) {

e.printStackTrace();

}

System.out.println("封装后:" + user);

// 以流的方式获取请求正文

ServletInputStream in = request.getInputStream();

int len = 0;

byte b[] = new byte[1024];

while((len = in.read(b)) != -1){

System.out.println(new String(b,0,len));

}

in.close();

**********************************************************************************************

3.4常用表单数据的获取

表单输入域类型:

radio checkbox,即使表单中有对应名称输入域,如果一个不选择,则什么数据不会带给服务器。(注意空指针异常)

如果选择了其中的一个或多个,则把他们的value的取值提交给服务器。

如果选择了其中的一个或多个,他们又没有value取值,则提交给服务器的值是on.

请求参数的编码:

浏览器当前使用什么编码,就以什么编码提交请求参数。

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

request.setCharacterEncoding(编码):

通知程序,客户端提交的数据使用的编码。但是只对POST请求方式有效(注意与response区分)

如果是get请求提交数据,编码就是ISO-8859-1;

Tips:目前采用POST提交方式。

Get方式: 字符转码:new String("中文".getBytes("ISO-8859-1"),"UTF-8");

采取全站中文编码过滤器方式即可

3.5域对象:

ServletRequest也是一个域对象(内部维护了一个Map<String,Object>)

Object getAttribute(Stirng name): (注意区分:request.getParameter(String name))

void setAttribute(String name,Object value):

void removeAttribute(String name):

3.6请求转发和重定向

请求转发借助于RequestDispatcher

如何得到RequestDispatcher对象:

方式一:ServletContext.getRequestDispatcher(目标资源的URI);

方式二:ServletRequest.getRequestDispatcher(目标资源的URI);

区别:

方式一中的目标资源的URI必须以"/"开头,否则报错,此"/"就表示的是当前应用(绝对路径表示法)

方式二中的目标资源的URI如果以"/"开头,就表示的是当前应用(绝对路径表示法)。如果不以"/"开头,就表示相对路径。

3.7转发和重定向细节(实际开发中知道一个原则) (了解原则)

请求转发:由源组件转发到目标组件时,容器会清空源组件输出的数据。

因此,用户只会看到目标组件输出的页面结果。但是,响应头信息是不清空的。

编码原则:不要在转发前后向页面输出数据,也不要关闭输出流。(做无用功)

区别:
转发,服务器的行为,发出了1次请求,地址栏不变;

重定向: 浏览器的行为,发出了2次请求,地址栏改变;

3.8包含:(动态包含)(了解原则)

由源组件包含到目标组件时,容器会清空目标组件的头。因此,源组件设置的头才有效。

但是,响应体信息是不清空的。

编码原则:不要在目标组件中设置响应头。(做无用功)

RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo2");

rd.include(request, response);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: