Servlet Class3

1.GET请求的语法

<a href="download?filename=1366768.jpg">下载图片</a><!-- get请求写法:地址?请求属性名=请求属性值-->

多个属性间用&分隔

2.通过设置响应头来实现下载功能

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="download?filename=1366768.jpg">下载图片</a>
<a href="download?filename=1366.jpg">下载图片</a>
<a href="download?filename=你好.txt">下载中文名称文档</a>
</body>
</html>
public class DownLoadServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String filename = request.getParameter("filename");
        File f = new File(this.getServletContext().getRealPath("download/"+filename));//获取服务器资源
        if(f.exists()) {//解决文件名中文问题
            String agent = request.getHeader("user-agent");
            if (agent.contains("MSIE")) {
                // IE浏览器
                filename = URLEncoder.encode(filename, "utf-8");
                filename = filename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器
                BASE64Encoder base64Encoder = new BASE64Encoder();
                filename = "=?utf-8?B?"
                        + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏览器
                filename = URLEncoder.encode(filename, "utf-8");                
            }
            response.setContentType(this.getServletContext().getMimeType(f.getPath()));//设置页面文件类型
            response.setHeader("Content-Disposition", "attachment;filename="+filename);//以附件方式打开文件
            ServletOutputStream sos = response.getOutputStream();
            FileInputStream fis = new FileInputStream(f);
            int len = 0;
            byte[] b = new byte[1024];
            while((len=fis.read(b))!=-1) {
                sos.write(b,0,len);
            }
            fis.close();
        }else {
            response.setContentType("text/html;charset=utf-8");//解决响应中文问题
            response.getWriter().println("<h2 style='color:red;'>文件不存在!</h2>");
        }
        
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

 3.验证码生成

public class CheckImgServlet extends HttpServlet {

    // 集合中保存所有成语
    private List<String> words = new ArrayList<String>();

    @Override
    public void init() throws ServletException {
        // 初始化阶段,读取new_words.txt
        // web工程中读取 文件,必须使用绝对磁盘路径
        String path = getServletContext().getRealPath("/WEB-INF/new_words.txt");
        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;
            while ((line = reader.readLine()) != null) {
                words.add(line);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 禁止缓存
        // response.setHeader("Cache-Control", "no-cache");
        // response.setHeader("Pragma", "no-cache");
        // response.setDateHeader("Expires", -1);

        int width = 120;
        int height = 30;

        // 步骤一 绘制一张内存中图片
        BufferedImage bufferedImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);

        // 步骤二 图片绘制背景颜色 ---通过绘图对象
        Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
        // 绘制任何图形之前 都必须指定一个颜色
        graphics.setColor(getRandColor(200, 250));
        graphics.fillRect(0, 0, width, height);

        // 步骤三 绘制边框
        graphics.setColor(Color.WHITE);
        graphics.drawRect(0, 0, width - 1, height - 1);

        // 步骤四 四个随机数字
        Graphics2D graphics2d = (Graphics2D) graphics;
        // 设置输出字体
        graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

        Random random = new Random();// 生成随机数
        int index = random.nextInt(words.size());
        String word = words.get(index);// 获得成语
        
        // 定义x坐标
        int x = 10;
        for (int i = 0; i < word.length(); i++) {
            // 随机颜色
            graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 旋转 -30 --- 30度
            int jiaodu = random.nextInt(60) - 30;
            // 换算弧度
            double theta = jiaodu * Math.PI / 180;

            // 获得字母数字
            char c = word.charAt(i);

            // 将c 输出到图片
            graphics2d.rotate(theta, x, 20);
            graphics2d.drawString(String.valueOf(c), x, 20);
            graphics2d.rotate(-theta, x, 20);
            x += 30;
        }

        // 将验证码内容保存session
        request.getSession().setAttribute("checkcode_session", word);

        // 步骤五 绘制干扰线
        graphics.setColor(getRandColor(160, 200));
        int x1;
        int x2;
        int y1;
        int y2;
        for (int i = 0; i < 30; i++) {
            x1 = random.nextInt(width);
            x2 = random.nextInt(12);
            y1 = random.nextInt(height);
            y2 = random.nextInt(12);
            graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
        }

        // 将上面图片输出到浏览器 ImageIO
        graphics.dispose();// 释放资源
        
        //将图片写到response.getOutputStream()中
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * 取其某一范围的color
     * 
     * @param fc
     *            int 范围参数1
     * @param bc
     *            int 范围参数2
     * @return Color
     */
    private Color getRandColor(int fc, int bc) {
        // 取其随机颜色
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

}

 使用案例:

注意,验证码中设置的Session值需要在另一个servlet中获取,利用输入的成语与生成的成语作比较,比较这一步也要放在servlet中,如果利用显示验证码的页面中定义js直接获取session值是获取不到的、或者是获取到前一个已经过期的session值,验证码图片之前是隐藏的,满足一定条件后显示,所以随着页刷新session值一直在改变。

即使在满足一定条件后再给img的src填写地址,也会导致session值被设置,但是在当前页面不刷新的情况下,直接获取必然是null,在页面再次刷新后,图片也再次刷新,此时虽然能获取到session值,但也是前一次生成的值,导致你获取到的session值永远是过期的,这里要利用ajax向验证servlet发送请求,根据返回的Text来进行操作。

究其原因,是因为页面运行在客户端,而session保存在服务端,只有客户端发起一次请求后,才能获取到session值,而servlet运行在服务端,可以随时获取到session值。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
    * {
        margin: 0px;
        padding: 0px;
    }
    .form {
        position: absolute;
        top: 350px;
        left: 462px;
        height: 300px;
         700px;
    }
    body {
        background-color: #c1c1c1;
    }
    .header {
        position: absolute;
        top: -50px;
        left: 230px;
    }
</style>
<script>
$(document).ready(function(){
            var uname = document.getElementById("uname");
            var pwd = document.getElementById("pwd");
            var uspan = document.getElementById("uspan");
            var pspan = document.getElementById("pspan");
            var message = "${message }";
            if(message !=""){
                var wrong = parseInt("${wrong}");
                if(wrong>=2){//输错两次显示验证码
                     $("#code").show();
                     document.getElementById("lbtn").disabled=true;
                }
                uname.style.borderColor = "red";
                pwd.style.borderColor = "red";
                uspan.innerHTML = "×"+message;
                   pspan.innerHTML = "×"+message;        
            }
        });
    
    </script>
</head>
<c:if test="${!empty cookie.logSta &&cookie.logSta.value eq '1'}">
    <c:redirect url="success.jsp?uname=${cookie.uname.value }"/>
</c:if>
<body style="overflow:hidden;">
<div class="header">
    <img src="img/1.png" alt="" height="50%" width="80%">
</div>
<div class="form">
    <form class="form-horizontal" role="form" action="login"  method="post">
      <div class="form-group">
        <label for="firstname" class="col-sm-2 control-label">用户名</label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="uname" placeholder="请输入用户名" name="user" style="200px;display:inline;">
          <span style="color:red;" id="uspan"></span>
        </div>
      </div>
      <div class="form-group">
        <label for="lastname" class="col-sm-2 control-label">密码</label>
        <div class="col-sm-10">
          <input type="password" class="form-control" id="pwd" placeholder="请输密码" name="pwd" style="200px;display:inline;">
          <span style="color:red;" id="pspan"></span>
        </div>
      </div>
      <div class="form-group" id="code" style="display:none;">
        <label for="lastname" class="col-sm-2 control-label">验证码</label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="checkImg" placeholder="请输验证码"  style="200px;display:inline;" onBlur="check()">
          <img src="checkImg" onClick="changeImg(this)" id="img">
        </div>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
          <div class="checkbox">
            <label>
              <input type="checkbox" name="autologin">请记住我
            </label>
          </div>
        </div>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
          <button type="submit" class="btn btn-default" id="lbtn">登录</button>
          <a class="btn btn-primary" href="signUp.html">注册</a>
        </div>
      </div>
    </form>
</div>
<script>
var count = 0;
function changeImg(obj){
    obj.src="checkImg?time="+count;
    count++;
    if(count==650){
        count = 0;
    }
}
var xmlhttp;
var checkImg = document.getElementById('checkImg');
function check(){
        var val = checkImg.value;
        var url = "check?val="+val;//向验证地址提交输入的值
        xmlhttp =new XMLHttpRequest();
        xmlhttp.onreadystatechange=checkResult; 
        xmlhttp.open("GET",url,true); 
        xmlhttp.send();  
}
function checkResult(){
        if (xmlhttp.readyState==4 && xmlhttp.status==200){
            var result = xmlhttp.responseText;//获取返回的文本
            if(result=="yes"){
                checkImg.style.borderColor="green";
                document.getElementById("lbtn").disabled=false;
            }else{
                checkImg.style.borderColor="red";
                document.getElementById("lbtn").disabled=true;
            }
        }
}
</script>
</body>
</html>
package com.login.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.login.model.dao.UserDAO;

public class LoginServlet extends HttpServlet{
    private UserDAO userDAO = new UserDAO(); 
    private int wrong;
    @Override
    public void init() {
        wrong = 0;
    }
    @Override
    protected void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException {
        //doPost(request,response);
        
    }
    @Override
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException {
        
        String user = request.getParameter("user");
        String pwd = request.getParameter("pwd");
        String autologin = request.getParameter("autologin");
        if(!userDAO.login(user, pwd)) {
            wrong++;//设置错误次数
            request.setAttribute("wrong", wrong);
            request.setAttribute("message", "账户名或密码错误!");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }else {
            wrong = 0;
            if(autologin!=null) {
                Cookie uname = new Cookie("uname",user);
                Cookie logSta = new Cookie("logSta","1");//保存用户登录状态码
                logSta.setMaxAge(60*60*24*7);//有效期一周
                uname.setMaxAge(60*60*24*7);
                response.addCookie(logSta);
                response.addCookie(uname);
            }
            request.setAttribute("user", user);
            request.getRequestDispatcher("success.jsp").forward(request, response);
        }
    }
}
package com.login.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CheckServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String word = (String) request.getSession().getAttribute("checkcode_session");
        response.setContentType("text/html;charset=utf-8");
        if(request.getParameter("val").equals(word)){//输入值和生成值作比较    
            response.getWriter().print("yes");
        }else {
            response.getWriter().print("no");
        }
    
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
原文地址:https://www.cnblogs.com/whwjava/p/9002075.html