【Java Web】JSP实现数据传递和保存(中)中文乱码 转发与重定向
文章目录
- 中文乱码
- 转发与重定向
- 转发
- 重定向
- 区别
- 升级示例1
中文乱码
JSP 中默认使用的字符编码方式:iso-8859-1,不支持中文。常见的支持中文的编码方式及其收录的字符:
- gb2312:常用简体汉字
- gbk:简体和繁体汉字
- utf-8:所有国家需要的字符
在 Java Web 应用程序中处理字符编码问题的几种方法
设置请求和响应的编码方式:
// 请求乱码:指定从客户端发送到服务器的数据(如表单提交)的字符编码
request.setCharacterEncoding("utf-8");
// 响应乱码:设置响应给客户端的 HTTP 内容的字符编码
response.setCharacterEncoding("utf-8");
<% // 在JSP页面顶部使用的指令,告诉浏览器以 UTF-8 格式解析页面%>
<%@ page language="java" contentType="text/html; charset=utf-8"%>
GET 请求出现乱码:
当使用GET方法传递参数时,由于URL中的参数通常是用ISO-8859-1编码传输的,如果直接读取可能会遇到中文乱码问题。
治标的方法:new String(变量名.getBytes("iso-8859-1"), "utf-8" )
- 将字符串先按照 ISO-8859-1 解码为字节数组,然后按照 UTF-8 重新编码成字符串。
治本的方法:通过配置Tomcat的server.xml
文件,在<Connector>
标签内添加或修改属性
URIEncoding="UTF-8"
、useBodyEncodingForURI="true"
正确地处理包含非英文字符的URL参数。
在tomcat\conf\server.xml
文件中找到相应的<Connector>
元素,并确保它包含如下配置
<Connector connectionTimeout="20000"
port="8080"
protocol="HTTP/1.1"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"/>
一般只设置 URIEncoding=“UTF-8” 就ok
转发与重定向
转发(Forward)和重定向(Redirect)是两种常见的请求处理方式,它们都可以用来将用户从一个资源引导到另一个资源,但实现机制和应用场景有所不同。
转发
在服务器端进行的操作,当一个Servlet或JSP页面接收到请求后,它可以通过RequestDispatcher
对象将请求转发给另一个资源(如另一个Servlet、JSP页面等),而客户端对此并不知情。转发过程中URL不会发生变化,对于用户来说就像是访问了一个单一的资源。
特点
- 请求仍然在同一个HTTP请求内完成。
- 服务器端控制整个过程,对客户端透明。
- 可以共享请求作用域中的数据(通过
HttpServletRequest
的setAttribute
方法设置的数据)。 - 适合于内部资源间的跳转,比如从一个Servlet跳转到一个JSP页面显示结果。
常见方式
在Servlet中使用RequestDispatcher
的forward
方法
// 获取RequestDispatcher
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/targetPage.jsp");
// 转发请求
dispatcher.forward(request, response);
在JSP页面中使用<jsp:forward>
动作标签
<jsp:forward page="/WEB-INF/jsp/targetPage.jsp">
...
</jsp:forward>
转发的工作方式
重定向
重定向是一个两步的过程,首先服务器发送一个特殊的响应给浏览器,告诉浏览器去请求一个新的URL。浏览器会用这个新的URL发起一个新的请求。这意味着重定向会导致浏览器地址栏中的URL发生变化。
特点
- 涉及两次独立的HTTP请求。
- 客户端可见,因为浏览器地址栏中的URL会发生变化。
- 不可以共享原始请求中的数据;如果需要传递信息,通常使用查询字符串或者Session。
- 适用于跨域跳转、外部网站链接以及某些安全性考虑的情况,例如登录成功后的跳转。
response.sendRedirect("http://example.com/anotherPage.html");
重定向的工作方式
区别
转发是服务器行为,重定向是客户端行为。
// 转发
request.getRequestDispatcher("url").forward(request, response);
// 重定向
response.sendRedirect("url");
- 转发可以携带参数,重定向不可以
- 转发 url 不会发生变化,重定向会
- 转发不会重新发送请求,重定向会
- 转发只能跳转当前项目路径,重定向可以跳转任意 url
升级示例1
HTML 表单内容不变化
<form action="dologin.jsp" method="post">
账号:<input type="text" name="uname"/><br/>
密码:<input type="text" name="upwd"/><br/>
<input type="submit"/>
</form>
不再存储登录信息,改跳转方式转发为重定向,去到【doindex.jsp】
<%
// 解决 post 中文乱码问题(必须放在接收参数之前)
request.setCharacterEncoding("utf-8");
// 接收参数
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
// 调用 Java 方法 登录
SmbmsUserDao smbmsUserDao = new SmbmsUserDaoImpl();
SmbmsUser smbmsUser = smbmsUserDao.login(uname,upwd);
// 判断登录是否成功
if (smbmsUser != null) {
// setAttribute 存储登录信息
// request.setAttribute("smbmsUserName",smbmsUser.getUserName());
// 转发
// request.getRequestDispatcher("index.jsp").forward(request,response);
// 重定向
response.sendRedirect("doindex.jsp");
} else {
// 登录失败则重定向回登录界面
response.sendRedirect("login.jsp");
}
%>
doindex.jsp
作为一个中间处理页面,主要负责调用业务逻辑(例如获取供应商列表信息)并将结果存储到请求作用域中,然后将请求转发给 index.jsp
进行视图展示。这种方式相比直接在 index.jsp
中执行业务逻辑,可以做到逻辑与视图分离,增强可读性和可维护性;提高复用性;增强安全性。
<%
// 调用 Java 方法 获取供应商列表信息
SmbmsProviderDao smbmsProviderDao = new SmbmsProviderDaoImpl();
List<SmbmsProvider> providerList = smbmsProviderDao.findAll();
// setAttribute 存储供应商信息
request.setAttribute("providerList",providerList);
// 转发
request.getRequestDispatcher("index.jsp").forward(request,response);
%>
不再获取登录信息,处理业务逻辑的部分交由 doindex.jsp
实现。
<%
// getAttribute 获取登录信息
// String name = request.getAttribute("smbmsUserName").toString();
// getAttribute 获取供应商信息
List<SmbmsProvider> smbmsProviderList = (List<SmbmsProvider>)request.getAttribute("providerList");
%>
<h1>
<%-- <%= name%> --%>
欢迎您登录 供应商信管理系统!!!
</h1>
<table border="1">
<tr>
<th>ID</th>
<th>proCode</th>
<th>proName</th>
<th>proDesc</th>
</tr>
<% for(SmbmsProvider smbmsProvider : smbmsProviderList){ %>
<tr>
<td><%= smbmsProvider.getId()%></td>
<td><%= smbmsProvider.getProCode()%></td>
<td><%= smbmsProvider.getProName()%></td>
<td><%= smbmsProvider.getProDesc()%></td>
</tr>
<% } %>
</table>
<%
// session.getAttribute 获取登录信息
SmbmsUser smbmsUser = (SmbmsUser)session.getAttribute("smbmsUser");
// getAttribute 获取供应商信息
List<SmbmsProvider> smbmsProviderList = (List<SmbmsProvider>)request.getAttribute("providerList");
%>
<h1>
<%=smbmsUser.getUserName()%>
欢迎您登录 供应商信管理系统!!!
</h1>
<form action="logout.jsp" method="get">
<input type="submit" value="安全退出"/>
</form>