学习内容:学习JavaWeb(Day39)
1、关于页面乱码 2、异常的处理 3、使用Token机制处理表单重复提交 4、jcaptcha验证码 5、Commons Codec
1、关于页面乱码
(1)页面请求转发时出现乱码,可能是因为转发的页面是在当前地址下调用的,所以会继承转发之前页面的编码格式,可以试着修改转发之前的编码格式。 重定向出现乱码,可能是因为重定向后页面的编码格式被重新设置,默认为浏览器的编码格式导致乱码。
2、异常的处理
(1)当数据库出现问题时, 三个步骤: 1.将异常转换为非强制捕获型异常 2.将异常向上层抛出,并统一处理 3.在错误页面给出客户友好提示,并通知管理员处理异常信息
(2)自定义异常
public class DataAccessException extends RuntimeException{
public DataAccessException(){}
public DataAccessException(String msg){
super(msg);
}
public DataAccessException(Throwable th){
super(th);
}
public DataAccessException(Throwable th,String msg){
super(msg,th);
}
}
将异常转换为非强制捕获型异常,并向上抛出统一处理
try {
conn = getConnection();
stat = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
stat.setObject(i + 1, params[i]);
}
rs = stat.executeQuery();
while (rs.next()) {
obj = rowMapper.mapperRow(rs);
}
} catch (SQLException sqlException) {
throw new DataAccessException(sqlException,"服务器正在升级,请稍后再试");
}
设计出错页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>服务器正在升级中,请稍后重试!</h1>
</body>
</html>
在web.xml文件中配置出错跳转位置
<error-page>
<error-code>500</error-code>
<location>/ErrorMsg.jsp</location>
</error-page>
<error-page>
<exception-type>com.hisoft.news.exception.DataAccessException</exception-type>
<location>/ErrorMsg.jsp</location>
</error-page>
设计错误页
<%-- isErrorPage="true"代表这是一个错误页 --%>
<%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Throwable th = null;
/* if (exception != null) { //exception是个内置对象,代表当前异常
th = exception;
}*/
if (request.getAttribute("javax.servlet.error.exception") != null) {
th = (Throwable) request.getAttribute("javax.servlet.error.exception");
}
if (th != null) {
// 输出当前请求的URI
out.println(request.getAttribute("javax.servlet.error.request_uri"));
// 输出导致错误页面被调用的Servlet的名字
out.println(request.getAttribute("javax.servlet.error.servlet_name"));
out.print(th); // 输出异常名称和异常信息
out.print(th.getMessage()); // 输出异常信息
}
%>
</body>
</html>
request作用域中的key还有: ? javax.servlet.error.status_code: Integer HTTP协议的状态代码 ? javax.servlet.error.exception_type: Class 未捕获异常的Class类的对象 ? javax.servlet.error.message: String 传递给sendError()方法的消息 ? javax.servlet.error.exception: Throwable 调用错误页面的未捕获异常 ? javax.servlet.error.request_uri: String 当前请求的URI ? javax.servlet.error.servlet_name: String 导致错误页面被调用的Servlet的名字
3、使用Token机制处理表单重复提交
(1)在表单页面,提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次。这是因为Servlet处理完请求以后,直接转发到目标页面,这样整个业务只发送了一次请求,那么当你在浏览器中点击刷新会一直都会刷新之前的请求。 这种情况可以使用重定向的方式跳转到目标页面,也可以使用token机制来处理。
(2)token机制:接收请求时,servlet生成一个唯一标识token,并放入session和request中,在表单中接收token,提交表单后验证表单的token和session的token是否相同,如果相同则说明是第一次提交,然后删除session中的token,如果第二次提交表单则会出现session不同,说明是重复提交。
@WebServlet("/form")
public class FormServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = UUID.randomUUID().toString();
HttpSession session = req.getSession();
session.setAttribute("token", token);
req.setAttribute("token", token);
req.getRequestDispatcher("form.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String money = req.getParameter("money");
String token = req.getParameter("token");
HttpSession session = req.getSession();
String sessionToken = (String) session.getAttribute("token");
if (token.equals(sessionToken)) {
System.out.println(money);
session.removeAttribute("token");
req.setAttribute("money", money);
req.getRequestDispatcher("succ.jsp").forward(req, resp);
} else {
resp.sendRedirect("msg.jsp");
}
}
}
表单接收token
<form action="/form" method="post">
<input type="hidden" value = "${requestScope.token}" name = "token">
请输入支付金额:<input type="text" name = "money"><br>
<input type="submit" value="支付">
</form>
成功页面
<body>
<h3>支付成功!支付总金额:${money}</h3>
</body>
提示页面
<body>
<h3>您已支付成功,请勿重复支付!!</h3>
</body>
4、jcaptcha验证码
(1)在官网下载jcaptcha包 https://jcaptcha.atlassian.net/wiki/display/general/Simple+Servlet+Integration+documentation
配置web.xml文件
<servlet>
<servlet-name>jcaptcha</servlet-name>
<servlet-class>com.octo.captcha.module.servlet.image.SimpleImageCaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jcaptcha</servlet-name>
<url-pattern>/jcaptcha.jpg</url-pattern>
</servlet-mapping>
表单中输入验证码内容,显示验证码图片
<form action="/form" method="post">
<input type="text" name="jcaptcha" id = "">
<img src="jcaptcha.jpg" /><a href="javaScript:void(0)" id = "btn">看不清换一张</a>
<input type="submit" value="支付">
</form>
验证
String userCaptchaResponse = request.getParameter("jcaptcha");
boolean captchaPassed = SimpleImageCaptchaServlet.validateRespons (request,userCaptchaResponse);
if(captchaPassed){
}else{
}
5、Commons Codec
(1)commons-codec是Apache开源组织提供的用于摘要运算、编码解码的包。常见的编码解码工具Base64、MD5、Hex、SHA1、DES等。
String md5 = DigestUtils.md5Hex("000000");
System.out.println(md5);
String sha1 = DigestUtils.shaHex("000000");
System.out.println(sha1);
(2)JavaScript加密库:前端的数据提交到后台之前对重要数据进行加密
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/sha1.js"></script>
<script>
var hash = CryptoJS.SHA1("Message");
</script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/md5.js"></script>
<script>
var hash = CryptoJS.MD5("Message");
</script>
|