request 对象是服务器对浏览器请求的封装,而 response 是服务器对服务器响应的封装。
request 用来取出请求信息,而 response 则用来添加要返回给浏览器的信息。
用来生成 Http 响应信息,发送给用户。
响应首行:
HTTP/1.1 200 OK
响应头:
key:value
几个常见的响应头:
html 中 meta 标签的作用就是用于向响应头中添加信息。
响应空行
一个分隔符
响应正文
需要发送的资源
用来生成http请求信息。
请求首行:
请求方式 请求路径 协议/版本号
请求头:
键值对
请求空行:
请求正文(post才有):
但是以下方法,无论是get还是post请求都可以获得参数值
请见CSDN博主「veejaLiu」的原创文章 https://blog.csdn.net/u014565127/article/details/78916262
请见CSDN博主「小小小丸子儿」的原创文章 https://blog.csdn.net/Dream_your/article/details/82050458
请见CSDN博主「王如霜」的原创文章 https://blog.csdn.net/wrs120/article/details/79287607
// 错×
String mess=request.getAttribute("mess");
mess. length();
// 对√
String mess=(String)request.getAttribute("mess");
if(mess!=null && !“”.equals(mess)){
// 在请求中取到"mess"属性对应的属性值,正常
// 使用mess数据
}else{
// 在请求中没有取到"mess"属性对应的属性值,
// 使用备选方案
}
解决方案:在conf/server.xml 中 URIEncoding=“UTF-8” 69行,
<Connector URIEncoding="UTF-8"
connectionTimeout="20000"
port="8888"
protocol="HTTP/1.1"
redirectPort="8443"/>
设置 URIEncoding 为 UTF-8。
服务器响应时的数据,即服务器向浏览器传递的数据的编码格式由服务器决定:
编码时使用的编码表,使用 getByte(“编码表”)
设置,或者使用 response.setCharacterEncoding(编码表)
设置。
两者的区别在于 ,前者设置字节流码表,后者设置字符流码表。
解码时使用的编码表,使用 response.setHeader(“ContentType”,“text/html;charset=utf-8”)
指定http响应头来设置。
GET提交,参数在URL中,设置URL的解码配置,服务器默认使用 IOS-8855-1 拉丁码表解码 URL,我们可以通过 tomcat/config/server.xml 配置文件中:
<Connector
connectionTimeout="20000"
port="8080"
protocol="HTTP/1.1"
redirectPort="8443"/>
添加属性 URIEncoding=“UTF-8”
即可将服务器默认的解码 url 的方式设置为 utf-8。
或者在 doget 方法中,将接收的乱码文字使用新的码表转换:
String name = request.getParamter("name"); // 获取乱码文字
byte[] bs = name.getBytes("IOS-8859-1"); // 根据乱码码表,将文字转换为字节数组
String s = new String(bs, "UTF-8"); // 将字节数组按照新的码表解码,生成文字
与GET提交解码的区别:
解码事件不同,GET 因为参数在 URL 中,所以服务器一旦接受请求就会立刻解码参数,而 POST 在 Servlet 调用获取参数的方法时才会解码。
所以,解决 POST 请求的乱码很简单,只需要在参数调用前使用即可。
request.setCharacterEncoding("utf-8");
设置请求解码表即可。
这就是请求转发,浏览器发送请求,servlet 处理 request 和 response 部分业务,但是无法全部处理,也无法简单的显示到页面中,所以将处理过得 request 和 response 发送给 JSP,JSP 进行一些业务操作,并响应给浏览器,展示。
请求转发主要用来分工操作。
AServlet doGet():
// ***** 不标准自定义转发
//todo AServlet进行业务处理,比如从数据库获取数据
// 处理结束后:=>
// 发送给Bservlet
BServlet bServlet = new BServlet();
bServlet.doGet(request, response);
//*****标准转发
// 使用request域(一个请求内有效,主要用于请求转发) 保存数据库的信息,发送给BServlet,即 AServlet和BServlet使用request域共享数据,request域是request对象中的一个Map。
request.setAttribute("name","Feathers"); // 向request域中存入一个键值对
request.getRequestDispatcher("/servlet/BServlet").forword(request.response);
BServlet doGet():
// todo 负责输出显示
// 从request域中取出值
System.out.println((String)request.getAttribute("name"));
注意:
不能在转发的Servlet中向浏览器输出任何响应正文的内容,但是可以添加响应头。因为Servlet中,即使你添加了响应体,也会被清空。
实现重定向很简单,只需要两个步骤:
// 在响应头中添加302状态码,告诉浏览器需要进行重定向
response.setStatus(302)
// 在响应头中添加Location,指定重定向的位置
response.setHeader("Location", "http://www.baidu.com");
当用户请求 servlet 时,服务器返回一个类似上面的响应头,上面的信息告诉浏览器,应该重新进行一次请求,请求的地址为 Header 中的 Location 地址。
所以,请求重定向实际上是两次请求。
只需要一个步骤:
response.setRedirect("http://www.baidu.com")
请求转发时,转发的 Servlet 不能修改请求体,而请求包含中,同请求转发类似,但是可以修改请求体。
用途:用来解决重复操作。
将重复的操作提取到这个 Servlet 中,统一进行处理。
往往在多个JSP中使用,一个jsp用于处理相同的操作,其余的jsp根据是否需要处理,进行依次处理。
实现:
AServlet doGet():
response.setContentType("text/html;charset=utf-8");
// 包含
request.getRequestDispatcher("/servlet/BServlet").include(request,response);
response.getWriter().write("Aservlet 处理");
BServlet doGet():
response.getWriter().write("Bservlet 处理");
结果:
Aservlet 处理Bservlet 处理
请见CSDN博主「fangaoxin」的原创文章 https://blog.csdn.net/fangaoxin/article/details/6952954
请见CSDN博主「小小莫者」的原创文章
https://blog.csdn.net/rshp_520/article/details/22213399
使用示例(网站访客计数器):
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Random" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>application主页</title>
<%
//application作用于整个服务器(全局)的存储数据的地方,一般不到万不得已不用,否则new的越多,服务器越崩(占内存)
int count = 1000000;
if(application.getAttribute("count") == null){
application.setAttribute("count", 1000000);
}else{
int c = (int)application.getAttribute("count");
c += new Random().nextInt(10000);
count = c;
application.setAttribute("count", c);
}
%>
</head>
<body>
<h1>欢迎您!您是我们网站的第<%=count %>个访问者</h1>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>登录界面title>
head>
<body>
<form action="/day_0904_web2/login1.jsp" method="get">
用户名称:<input type="text" name="cu_name" /><br />
用户电话:<input type="password" name="cu_phone" /><br />
兴趣爱好:
<input type="checkbox" name="happy" value="1" />足球
<input type="checkbox" name="happy" value="2" />篮球
<input type="checkbox" name="happy" value="3" />网球
<input type="checkbox" name="happy" value="4" />排球
<br />
<input type="submit" value="登录" />
form>
body>
html>
login.jsp:
<%@ page language="java" import="java.util.Arrays" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>接收登录页面传递来的数据title>
<%
// 从index.jsp页面传递来的数据,使用request来获取
// 拿数据,用请求;发送数据,用响应
String cu_name = request.getParameter("cu_name");
String cu_phone = request.getParameter("cu_phone");
String[] happys = request.getParameterValues("happy");
%>
head>
<body>
你提交的用户名称是:<%=cu_name %><br />
你提交的用户电话是:<%=cu_phone %><br />
你提交的兴趣爱好是:<%=Arrays.toString(happys) %>
body>
html>
login1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>login1title>
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String cu_name = request.getParameter("cu_name");
String cu_phone = request.getParameter("cu_phone");
// 假设用户名是刘德华,密码是999
// 正确则跳转至欢迎页面,不正确则返回登录页面
if("刘德华".equals(cu_name) && "999".equals(cu_phone)){
// 跳转至欢迎页面
response.sendRedirect("/day_0904_web2/welcome.jsp?cu_name="+cu_name); //显式地将用户名传递
// request.getRequestDispatcher("") 将页面跳转,里面接收页面的跳转地址
// .forward(request, response) 将当前页面中的req和resp两个对象直接传递给下一个页面
// request.getRequestDispatcher("welcome.jsp").forward(request, response);
// 注意:对于服务器的跳转,是相对路径,相对当前页面(login1.jsp)
/*转发和重定向的区别
response跳转(重定向)结果:
http://localhost:8080/day_0904_web2/welcome.jsp?cu_name=???
request跳转(转发)结果:
http://localhost:8080/day_0904_web2/login1.jsp?cu_name=刘德华&cu_phone=999
response属于客户端行为,是由客户端(是浏览器行为,相当于直接在地址栏输入了一串代码)来发起跳转请求的
request属于服务器端行为,是由服务器内部来进行跳转的,服务器跳转了页面的地址,
而浏览器却不知道,所以浏览器的地址还停留在上一个页面的地址上
*/
}else{
// 返回登录页面
//response.sendRedirect(""); 接收1个字符串的参数,为需要跳转网页的地址
response.sendRedirect("/day_0904_web2");
// 另外的方法用的较少,不推荐
// out.print("<script type='text/javascript'>location.href='/day_0904_web2'script>");
}
%>
head>
<body>
body>
html>
welcome.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>欢迎页面title>
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
%>
head>
<body>
<h1>欢迎您!<%=request.getParameter("cu_name") %>h1>
body>
html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.URLDecoder" %>
<html>
<head>
<meta charset="UTF-8">
<title>登录界面title>
<%
// 读取cookie,并赋值给cu_name
String cu_name="";
// request.getCookies(): 获取浏览器中所有的cookie,如果没有,返回null
Cookie[] cookies = request.getCookies();
if(cookies != null && cookies.length>0){
for(Cookie c : cookies){
if("cu_name".equals(c.getName())){
String cu_name_utf8 = c.getValue();
// 解码
cu_name = URLDecoder.decode(cu_name_utf8, "utf-8");
}
}
}
// err验证,如果用户名或密码错误,则页面上会有显示
String e="";
if(request.getParameter("err") != null){
e=request.getParameter("err");
switch(e){
case "1":
out.println("<script type='text/javascript'>window.onload=function(){p1.style.display='block';} script>");
}
}
%>
<style type="text/css">
#p1{
display:none;
}
style>
head>
<body>
<p id="p1">用户名或密码错误!p>
<form action="/day_0905_web3/login.jsp" method="post">
用户名称:<input type="text" name="cu_name" value="<%=cu_name %>" /><br />
用户密码:<input type="password" name="cu_phone" /><br />
<input type="submit" value="登录" /><a href="/day_0905_web3/reg.jsp">还没有账号?a>
form>
<script type="text/javascript">
setTimeout(function(){
p1.style.display="none";
}, 5000);
script>
body>
html>
login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="javax.print.URIException" %>
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String cu_name = request.getParameter("cu_name");
String cu_phone = request.getParameter("cu_phone");
Connection conn = null;
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/ishopn?characterEncoding=utf8";
String user="root";
String password="170630";
conn = DriverManager.getConnection(url, user, password);
String sql = "select count(*) from customer where cu_name=? and cu_phone=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, cu_name);
ps.setString(2, cu_phone);
ResultSet rs = ps.executeQuery();
rs.next();
int c=rs.getInt(1);
if(c>0){
// cookie:临时以文件的形式(key-value对)将数据存储在用户的计算机上浏览器的temp文件夹
// 保存cookie是浏览器的动作,如果放在跳转之后,代码是执行的,但是浏览器已经跳转了,就无法保存了
// 当用户名和密码判断正确时,将用户名保存至cookie
// cookie如果中文乱码的解决方法
// 编码
/* 登录成功后将用户名保存至cookie → 保存cookie
* 下次登录读取cookie获取用户名称 → 读取cookie
* 登出 → 清楚cookie
*/
String cu_name_utf8 = URLEncoder.encode(cu_name, "utf-8");
Cookie cookie = new Cookie("cu_name", cu_name_utf8); // new Cookie(String key, String value)
cookie.setMaxAge(60); // 单位是秒,是cookie的最大保存时间,时间到了浏览器自动清理过期cookie,生命周期为MAX_VALUE则Cookie信息将永久有效
response.addCookie(cookie); // 输出到客户端
//以session来保存用户名称,即可解决中文的问题,只要在服务器端,就不存在中文乱码问题
// session的value可以存Object类型数据,而cookie的value只能存String类型数据
// 重新打开浏览器或不同的浏览器,算一次新的会话
// 在服务器接收到第一次请求时,就建立新的会话,服务器就会为这次会话创建一个整个服务器都唯一的sessionid
session.setAttribute("cu_name", cu_name);
// 从此以后就不需要用response传值了
//response.sendRedirect("/day_0905_web3/welcome.jsp?cu_name="+cu_name);
response.sendRedirect("/day_0905_web3/welcome.jsp");
}else{
response.sendRedirect("/day_0905_web3/index.jsp?err=1");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
%>
logout.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 实现登出功能,清出cookie后跳转至主页
Cookie c = new Cookie("cu_name", "");
c.setMaxAge(0); // 如果maxAge为0,则表示删除该Cookie
response.addCookie(c);
response.sendRedirect("/day_0905_web3");
%>
reg.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>注册页面title>
head>
<body>
<form action="/day_0905_web3/doreg.jsp" method="post" onsubmit="return check()">
用户名称:<input type="text" name="cu_name" /><br />
用户密码:<input type="password" name="cu_phone" /><br />
用户性别:<input type="radio" name="cu_gender" value="1" checked />男
<input type="radio" name="cu_gender" value="0" />女<br />
用户地址:<input type="text" name="cu_address" /><br />
<input type="submit" value="注册" /><a href="/day_0905_web3">已经有账号了a>
form>
<script type="text/javascript" src="/day_0905_web3/js/reg.js">script>
body>
html>
doreg.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="java.util.UUID" %>
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String cu_id = UUID.randomUUID().toString();
String cu_name = request.getParameter("cu_name");
String cu_phone = request.getParameter("cu_phone");
String cu_gender=request.getParameter("cu_gender");
String cu_address=request.getParameter("cu_address");
Connection conn = null;
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/ishopn?characterEncoding=utf8";
String user="root";
String password="170630";
conn = DriverManager.getConnection(url, user, password);
String sql = "insert into customer (cu_id,cu_name,cu_phone,cu_gender,cu_address) values (?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, cu_id);
ps.setString(2, cu_name);
ps.setString(3, cu_phone);
ps.setInt(4, new Integer(cu_gender));
ps.setString(5, cu_address);
int line = ps.executeUpdate();
if(line>0){
response.sendRedirect("/day_0905_web3/welcome.jsp?cu_name="+cu_name);
}else{
response.sendRedirect("/day_0905_web3/index.jsp?err=2");
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
%>
welcome.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>welcome!</title>
</head>
<body>
<!-- <h1 align="center">欢迎您!<a href="/day_0905_web3/logout.jsp">< %=request.getParameter("cu_name") %></a></h1> -->
<!-- 用session代替上一行代码,浏览器welcome页面可显示中文,关闭浏览器后需重新登录才有,因为重新打开浏览器或不同的浏览器,算一次新的会话 -->
<h1 align="center">欢迎您!<a href="/day_0905_web3/logout.jsp"><%=session.getAttribute("cu_name") %></a></h1>
<!-- 将所有的商品信息以table表格的方式展示在这个页面中 -->
<%
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
Connection conn = null;
try{
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/ishopn?characterEncoding=utf8";
String user="root";
String password="170630";
conn = DriverManager.getConnection(url, user, password);
String sql = "select c_id,c_name,c_madein,ct_name,c_inprice,c_outprice,c_num from commodity inner join commoditytype on c_type=ct_id where c_outprice!=0";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
%>
<table border="1px" align="center" width="500" cellspacing="0" style="text-align:center">
<thead>
<tr>
<td>商品编号</td>
<td>商品名称</td>
<td>商品产地</td>
<td>商品类型</td>
<td>商品进价</td>
<td>商品售价</td>
<td>商品库存</td>
</tr>
</thead>
<tbody>
<%
while(rs.next()){
%>
<tr>
<td><%=rs.getString(1) %></td>
<td><%=rs.getString(2) %></td>
<td><%=rs.getString(3) %></td>
<td><%=rs.getString(4) %></td>
<td><%=rs.getInt(5) %></td>
<td><%=rs.getInt(6) %></td>
<td><%=rs.getInt(7) %></td>
</tr>
<%
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
%>
</tbody>
</table>
</body>
</html>
reg.js:
//window.οnlοad=function(){
// 获取元素
var inputs=document.getElementsByTagName("input");
var cu_name=document.getElementsByName("cu_name")[0];
var cu_phone=document.getElementsByName("cu_phone")[0];
// 操作元素
function check(){
for(var i=0; i<inputs.length; i++){
if(inputs[i].value==null || inputs[i].value==""){
alert("所有信息都不能为空");
inputs[i].focus();
return false;
}
}
if((cu_name.value).trim().length<=2){
alert("用户名至少3个字母");
return false;
}
if((cu_phone.value).trim().length<=3){
alert("密码至少4个字母");
return false;
}
return true;
}
//}
效果:
index.jsp:
reg.jsp:
welcome.jsp:
本文标题一、二、三的大部分内容为CSDN博主「Feathers .」的原创文章,原文链接:https://blog.csdn.net/xf616510229/article/details/53483472