request、response、编码和路径

1. response

response对象的功能分为以下四种:

  • 设置响应头信息;
  • 发送状态码;
  • 设置响应正文;
  • 重定向;

1.1 设置响应头信息

response.setHeader(“content-type”, “text/html;charset=utf-8)
// 设置content-type响应头,该头的作用是告诉浏览器响应内容为html类型,编码为utf-8。而且同时会设置response的字符流编码为utf-8,即response.setCharaceterEncoding(“utf-8”);
response.setHeader("Refresh","5; URL=http://www.itcast.cn")
// 5秒后自动跳转到传智主页

1.2 发送状态码及其他方法

response.setContentType("text/html;charset=utf-8"):等同与调用response.setHeader(“content-type”, “text/html;charset=utf-8);
response.setCharacterEncoding(“utf-8):设置字符响应流的字符编码为utf-8; 
response.setStatus(200):设置状态码;
response.sendError(404, “您要查找的资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面去,但可以显示错误信息。

1.3 设置响应正文

response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:

PrintWriter out = response.getWriter():获取字符流对象;
ServletOutputStream out = response.getOutputStream():获取字节流对象;

response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。
如果希望响应数据马上发送给客户端,需要调用response.flushBuffer()方法来手动刷新缓冲区;

1.4 重定向

  • 重定向是两次请求;
  • 重定向的URL可以是其他应用,不局限于当前应用;
  • 重定向的响应头为302,并且必须要有Location响应头;
  • 重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;

2. request

在这里插入图片描述
request的功能:

  • 封装了请求头数据;
  • 封装了请求正文数据,如果是GET请求,那么就没有正文;
  • request是一个域对象,可以把它当成Map来添加获取数据;
  • request提供了请求转发和请求包含功能。

2.1 请求头

String getHeader(String name):获取指定名称的请求头;
Enumeration getHeaderNames():获取所有请求头名称;
int getIntHeader(String name):获取值为int类型的请求头。

加粗样式

2.2 请求参数

String getParameter(String name):通过指定名称获取参数值;
String[] getParameterValues(String name):当多个参数名称相同时,可以使用方法来获取;
Enumeration getParameterNames():获取所有参数的名字;
Map getParameterMap():获取所有参数封装到Map中,其中key为参数名,value为参数。

2.3 域对象

request是域对象!一个请求只会创建一个request对象。
Servlet中三大域对象:request、session、application。

void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)
Enumeration getAttributeNames()

2.4 请求转发和请求包含

(1)一个请求跨多个Servlet,需要使用转发和包含。

RequestDispatcher rd = request.getRequestDispatcher("/MyServlet");  使用request获取RequestDispatcher对象,方法的参数是被转发或包含的Servlet的Servlet路径
请求转发:rd.forward(request,response);
请求包含:rd.include(request,response);
  • 请求转发:由下一个Servlet完成响应体!当前Servlet可以设置响应头!(留头不留体)
  • 请求包含:由两个Servlet共同完成响应体!(都留)
  • 无论是请求转发还是请求包含,都在一个请求范围内!使用同一个request和response

(2)请求转发与请求包含比较

  • 转发留头不留体,包含都可以留;
  • 请求包含大多是应用在JSP页面中,完成多页面的合并;
  • 请求转发大多是应用在Servlet中,转发目标大多是JSP页面;

(3)请求转发与重定向比较

  • 请求转发是一个请求,而重定向是两个请求
  • 请求转发后浏览器地址栏不会有变化,而重定向会有变化,因为重定向是两个请求;
  • 请求转发的目标只能是本应用中的资源,重定向的目标可以是其他应用;
  • 请求转发对AServlet和BServlet的请求方法是相同的,即要么都是GET,要么都是POST,因为请求转发是一个请求;
  • 重定向的第二个请求一定是GET;
  • 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名!
  • 请求转发和重定向效率是转发高!因为是一个请求!
  • 需要在下一个Servlet中获取request域中的数据,必须要使用转发!

3.编码

3.1 请求编码

在这里插入图片描述

  • 直接在地址栏给出请求
    不同浏览器使用不同的编码,所以这是不确定的!IE和FireFox:使用GB2312;而Chrome:使用UTF-8;

  • 在页面发出请求
    页面是服务器发送到客户端浏览器的,所以这个页面本身的编码由服务器决定。

<head>
    <title>index.html</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  • get请求解读编码
    request.getParameter()获取的数据是被服务器误认为ISO-8859-1编码的,所以需要使用ISO-8859-1解码再编码成需要的格式。
String name = request.getParameter(“name”);
name = new String(name.getBytes(“iso-8859-1), “utf-8);
  • post请求解读编码
    (1)先指定编码:request.setCharacterEncoding();再读取数据:reuqest.getParameter()
    (1)但如果没有指定编码,那么默认还是使用ISO-8859-1来解读。
request.setCharacterEncoding(“utf-8);
String name = request.getParameter(“name”);

3.2 响应编码

在这里插入图片描述
服务器默认的相应编码是ISO-8859-1,使用response.getWriter()发送数据之前,一定要设置response的编码:

response.setCharacterEncoding(“utf-8);

同时需要通知浏览器使用的解码方式:

response.setContentType(“text/html;charset=utf-8);

在静态页面中,使用<meta>来设置content-type响应头,例如:

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

3.3 URL编码

特殊字符需要先转换成URL编码格式,再发送给服务器。
表单自动使用URL编码,只有get请求需要手动设置编码:
这里使用JS修改:

 <script type="text/javascript">
 	function _go() {
 		location = "/day05_2/AServlet?name=" + encodeURIComponent("传智+播客");
 	}
 </script>
<a href="javascript:_go();">链接</a>

4.路径问题

4.1. 客户端路径和服务器端路径

  • 客户端路径需要给出应用名称,例如:/day05_1/AServlet
  • 服务器端路径无需给出应用名称,例如:/AServlet

4.2. 客户端路径

1). 页面中都是客户端路径:

  • <a>的href:如果不以“/”开头,那么相对当前.html页面所在路径
  • <form>的action
  • <img>的src

2). 重定向也是客户端路径:
以“/”开头:相对当前主机,例如:http://localhost:8080/,所以需要自己手动添加项目名

response.sendRedirect("/day05_1/BServlet");
相当于:http://localhost:8080/day05_1/BServlet

4.3. 服务器端路径

(1)<url-pattern>:也叫Servlet路径

  • 要么以“*”开关,要么为“/”开头

(2)请求转发和请求包含

  • 以“/”开头:相对当前项目路径,例如:http://localhost:8080/项目名/
request.getRequestdispacher("/BServlet")
==>文件地址 http://localhost:8080/项目名/BServlet.java 
  • 不以“/”开头:相对当前Servlet路径。
- request.getRequestdispacher("/BServlet");

假如当前Servlet是:http://localhost:8080/项目名/servlet/AServlet,
就是http://localhost:8080/项目名/servlet/BServlet

(3)ServletContext获取资源等
相对当前项目目录,即当然index.jsp所在目录(http://localhost:8080/项目名)

4.4 获取类路径资源

可以通过Class类的对象来获取类路径下的资源,对应JavaWeb应用的类路径就是classes目录下的资源。
类路径对一个JavaWeb项目而言,就是/WEB-INF/classes和/WEB-INF/lib/每个jar包!

常见方式

  • Class类的getResourceAsStream(String path):
    路径以“/”开头,相对classes路径;
    路径不以“/”开头,相对当前.class文件所在路径,例如在cn.itcast.servlet.MyServlet中执行,那么相对/classes/cn/itcast/servlet/路径;

  • ClassLoader类的getResourceAsStream(String path):
    相对classes路径;

例如
在这里插入图片描述

InputStream in = this.getClass().getResourceAsStream("/xxx.txt"); // 在classes文件夹内
System.out.println(IOUtils.toString(in));

InputStream in = this.getClass().getClassLoader().getResourceAsStream("xxx.txt");// 在classes文件夹
System.out.println(IOUtils.toString(in));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
var fs = require('fs'); var ejs = require('ejs'); var mysql = require('mysql'); var express = require('express'); var bodyParser = require('body-parser'); // 连接mysql数据库 var client = mysql.createConnection({ host: 'localhost', port:"3306", user: 'root', password: 'root123', database: 'my_db_1' }); // //判断是否连接成功 client.connect(function(err){ if(err){ console.log('[query] - :'+err); return; } console.log('[connection connect] Mysql数据库连接成功!'); }); // 解析请求体中的URL的编码数据 var app = express(); app.use(bodyParser.urlencoded({ extended: false })); // app.listen(52273, function () { console.log('服务器运行在 http://127.0.0.1:52273'); }); // app.get('/', function (request, response) { // fs.readFile('book-list.html', 'utf8', function (error, data) { // client.query('SELECT * FROM books', function (error, results) { // response.send(ejs.render(data, { data: results })); }); }); }); // app.get('/delete/:id', function (request, response) { // client.query('DELETE FROM books WHERE id=?', [request.params.id], function () { // response.redirect('/'); }); }); // app.get('/insert', function (request, response) { // fs.readFile('book-insert.html', 'utf8', function (error, data) { // response.send(data); }); }); // app.post('/insert', function (request, response) { // var body = request.body; // client.query('INSERT INTO books (bookname, author, press) VALUES (?, ?, ?)', [ body.bookname, body.author, body.press ], function () { // response.redirect('/'); }); }); // app.get('/edit/:id', function (request, response) { // fs.readFile('book-edit.html', 'utf8', function (error, data) { // client.query('SELECT * FROM books WHERE id = ?', [ request.params.id ], function (error, result) { // response.send(ejs.render(data, { data: result[0] })); }); }); }); // app.post('/edit/:id', function (request, response) { // var body = request.body; // client.query('UPDATE books SET bookname=?, author=?, press=? WHERE id=?', [body.bookname, body.author, body.press, request.params.id], function () { // response.redirect('/'); }); });补全注释
最新发布
06-06

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值