Java淘菜日志 04/18 网站注册和登录页面的简单制作

时间:2022-08-31 11:13:43

网站注册和登录页面的简单制作

需要用到的编程基础有哪些?

  • java基础
  • 数据库
  • JSP
  • JDBC
  • HTML5
  • CSS3
  • Servlet
  • JavaScript

几个需要用到的工具(示例)

以下工具为示例中所使用的工具,也可以使用相应的替代工具。

  • Navicat for MySQL
  • MyEclipse
  • Google浏览器

效果预览

index.jsp主页
Java淘菜日志 04/18 网站注册和登录页面的简单制作

login.jsp登录页
Java淘菜日志 04/18 网站注册和登录页面的简单制作

register.jsp注册页
Java淘菜日志 04/18 网站注册和登录页面的简单制作

[TODO]

功能介绍

  • 注册

目前大多数网页都已经逐渐优化,它们的注册相对简单快捷,大部分网页通过手机号获取验证码就能够注册一个网页的账号,由于笔者的菜鸟水平限制,这里只是简单地制作一个简化版的登录页。

表单内容包括:昵称、密码、手机号、验证码。通过通过简单的验证后(如输入非法字符,用户已存在,或密码长度不够等),用submit可以提交数据到数据库进行存储。

  • 登录

这里的登录界面包括两个输入框的验证,即username(用户名)和password(密码)。如果在表单中所输入的登录信息在数据库中所对应的用户储存表中有对应的信息,则登录成功。否则登录失败,并提示用户。此外,输入框中没有输入内容时,也为用户提供友好提示。

MVC模式思维导图

Java淘菜日志 04/18 网站注册和登录页面的简单制作

项目目录结构

Java淘菜日志 04/18 网站注册和登录页面的简单制作

实现步骤

一、【在数据库中建表】

1.在Navicat for MySQL创建一个连接
2.在所创建的连接中新建一个数据库
3.在新建的数据库中创建一张用于存储用户信息的表
表的信息主要包括:id, username, password, phonenum(也可根据需求添加相应的信息)
4.在所建的表中初始化部分用户

二、【MyEclipse准备工作】

1.创建web项目并在项目下的“WebRoot > WEB-INF > lib”目录下导入需要用到的相关的jar包(版本视具体情况而定)
c3p0-0.9.1.2.jar
commons-beanutils-1.8.3.jar
commons-logging-1.1.1.jar
mysql-connector-java-5.1.6.jar
2.根据思维导图在src中创建MVC三层结构所需要用到的包
bean(存放实体类)
dao(DAO层)
dao.Impl(用于存放dao层的实现类)
service(service层)
service.Impl(用于存放service层的实现类)
utils(用于存放工具类)
web(web层,用于存放servlet代码)
3.创建jsp文件
选择一:直接在WebRoot目录下分别创建注册和登录所需要的jsp文件
选择二:在WebRoot目录下新建一个Folder,然后在Folder下创建jsp文件
4.创建JDBC的连接池(以c3p0为例,配置文件代码也在下)
在src目录下创建xml的连接池配置文件(c3p0-config.xml)
注意:连接池中的的数据库名一定要与数据库保持一致
5.在src下创建new_words.txt文件(用于生成验证码图片)

这里以成语作为文本元素生成图片

即文档中的内容为:
一唱一和
一呼百应
一干二净
一举两得
一落千丈
一模一样
一暴十寒
一日千里……

三、【编写代码】

  1. 在src下创建配置c3p0的连接池配置文件c3p0-config.xml(注意:是在src下)

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 我们希望在配置文件中,出现链接的参数信息 -->
    <default-config>
        <!-- name 属性定义 链接参数的key 标签的内容 代表值 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///User</property>
        <property name="user">root</property>
        <property name="password">root</property>
    </default-config>
</c3p0-config>
  1. 在utils包编写需要用到的工具类

编写工具类cookieutils.java(用于封装提取cookie方法)


package utils;

import javax.servlet.http.Cookie;

public class cookieutils {
    public static Cookie getcookies(Cookie[] cookies, String name){
        if (cookies == null) {
            return null;
        }
        for (Cookie c: cookies) {
            if (c.getName().equals(name)) {
                return c;
            }
        }
        return null;
    }
}

编写工具类JdbcUtils.java


package utils;

import java.sql.Connection;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JdbcUtils {
    // 默认加载src 下面c3p0-config.xml加载
    private static ComboPooledDataSource ds = new ComboPooledDataSource();

    // 创建连接
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();

    }

    public static void close(Connection conn, Statement stmt) {
        try {// 判断
            if (stmt != null) {
                stmt.close();
                stmt = null;// gc 一个变量被赋值为null, 垃圾回收机制。 会优先处理这些对象。
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                conn.close();
                conn = null;// gc 一个变量被赋值为null, 垃圾回收机制。 会优先处理这些对象。
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        // 6.关闭连接(后打开的先关闭)
        try {
            if (rs != null) {
                rs.close();
                rs = null;// gc 一个变量被赋值为null, 垃圾回收机制。 会优先处理这些对象。
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (stmt != null) {
                stmt.close();
                stmt = null;// gc 一个变量被赋值为null, 垃圾回收机制。 会优先处理这些对象。
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                conn.close();
                conn = null;// gc 一个变量被赋值为null, 垃圾回收机制。 会优先处理这些对象。
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  1. 编写JSP显示页面

编写主页index.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>我们的主页</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <style type="text/css"> * { list-style-type: none; padding: 0; margin: 0; text-decoration: none; } body{ background-color: beige; } .bod { height: 100%; width: 100%; font-family: "微软雅黑"; color: darkslategrey; font-size: 14px; } h1{ font-family: "楷体"; font-size: 40px; line-height: 200px; margin-top: 200px; vertical-align: middle; text-align: center; } P{ text-align: center; } .but{ margin: 40px; padding: 10px; display: inline; height: 50px; width: 100px; color: goldenrod; border: 1px solid darkgray; background-color: gainsboro; } </style>
  </head>

  <body>
    <div class="bod">
            <h1>假 设 这 里 是 主 页</h1>
            <p>
                <a href="/user/register.jsp"><span class="but">用 户 注 册</span></a>
                <a href="/user/login.jsp"><span class="but">用 户 登 录</span></a>
            </p>
        </div>
  </body>
</html>

创建页面文件login.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>用户登录</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <style type="text/css"> * { list-style-type: none; padding: 0; margin: 0; text-decoration: none; } body{ background-color: beige; } .bod { height: 100%; width: 100%; font-family: "微软雅黑"; color: darkslategrey; font-size: 14px; } .login { width: 350px; margin: 150px auto; padding: 50px; background-color: gainsboro; border: 1px solid burlywood; } p{ margin: 20px; } #tit{ width: 100%; margin: 0 auto; } .note{ font-family: "楷体"; color: orangered; font-size: 14px; } #submit{ border: none; height: 30px; width: 100px; color: white; font-weight: bold; background-color: darkred; } </style>

  </head>

  <body>
    <script type="text/javascript"> function chang(){ var _img = document.getElementById("_img"); var date = new Date(); _img.src ="/user/checkImgServlet?" + date.toLocaleTimeString(); } </script>
    <div class="bod">
            <div class="login">
                <p id="tit"><h2>用 户 登 录</h4></p>
                <form action="/user/login" method="post">
                    <p>用户名:<input type="text" name="username" value="${cookie.name.value}" style="width: 130px;" /><span class="note">${msg1}</span></p>
                    <p>登录码:<input type="password" name="password" value="${cookie.pwd.value}" style="width: 130px;" /><span class="note">${msg2}</span></p>
                    <p>验证码:<input type="text" name="imgcheck" style="width: 130px;"><span class="note">${msg}</span><p/>
                    <img alt="图片走丢了" src="/user/checkImgServlet" id="_img" onclick="chang()" style="padding-left: 60px; margin-top: -20px" />
                    <p><font size="3"><input type="checkbox" name="remember" checked="checked"/>记住密码</font></p>
                    <p><input type="submit" id="submit" value="立 即 登 录" /><span class="note">${msg3}</span></p>
                    <p><a href="/user/index.jsp"><span id="submit"> 返 回 主 页 </span></a></p>
                </form>
            </div>
        </div>
  </body>
</html>

创建页面文件register.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>用户注册</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <style type="text/css"> * { list-style-type: none; padding: 0; margin: 0; text-decoration: none; } body{ background-color: beige; } .bod { height: 100%; width: 100%; font-family: "微软雅黑"; color: darkslategrey; font-size: 14px; } .login { width: 400px; margin: 150px auto; padding: 50px; background-color: gainsboro; border: 1px solid burlywood; } p{ margin: 20px; } #tit{ width: 100%; margin: 0 auto; } .note{ font-family: "楷体"; color: orangered; font-size: 12px; } #submit{ border: none; height: 30px; width: 100px; color: antiquewhite; font-weight: bold; background-color: darkred; } </style>
  </head>

  <body>
    <div class="bod">
            <div class="login">
                <p id="tit"><h2>用 户 注 册</h4></p>
                <form action="/user/register" method="post">
                    <p>用户名: <input type="text" name="username" style="width: 130px;" /><span class="note">${smg1}</span></p>
                    <p>手机号: <input type="text" name="phonenum" style="width: 130px;" /><span class="note">${smg1}</span></p>
                    <p>登录码: <input type="password" name="password" style="width: 130px;" /><span class="note">${msg2}</span></p>
                    <p><input type="submit" id="submit" value="立 即 注 册" /><span class="note">${msg3}</span></p>
                    <p><a href="/user/index.jsp"><span id="submit"> 放 弃 注 册 </span></a></p>
                </form>
            </div>
        </div>
  </body>
</html>
  1. 在bean包下创建一个实体类User

package bean;

/** * @author 雪根 * @description 实体类:封装用户信息 */
public class User {
    private int id;
    private String username;
    private String password;
    private String phonenum;

    /** * 无参构造方法 */
    public User() {
        super();
    }

    /** * 有参构造方法 */
    public User(int id, String username, String password, String phonenum) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.phonenum = phonenum;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhonenum() {
        return phonenum;
    }

    public void setPhonenum(String phonenum) {
        this.phonenum = phonenum;
    }
}
  1. 依次创建dao层、service层的接口(其作用主要是便于代码的扩展),并定义方法

创建dao层接口UserDaoInter

package dao;

import bean.User;

public interface UserDaoInter {
    public User login(User user);

    public boolean register(User user);

    public boolean UsernameExist(User user);
}

创建dao层接口UserServiceInter

package service;

import bean.User;

public interface UserServiceInter {
    public User login(User user);

    public boolean register(User user);

    public boolean UsernameExist(User user);
}
  1. 分别创建dao层和service层的实现类

创建UserServiceInter的实现类UserDaoImpl


package dao.Impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import utils.JdbcUtils;
import bean.User;
import dao.UserDaoInter;

public class UserDaoImpl implements UserDaoInter {
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;
    String sql = null;

    public User login(User user) {
        try {
            conn = JdbcUtils.getConnection();
            sql = "select * from user where username = ? and password = ?";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, user.getUsername());
            stmt.setString(2, user.getPassword());
            rs = stmt.executeQuery();
            if (rs.next()) {
                User u = new User();
                u.setUsername(rs.getString("username"));
                u.setPassword(rs.getString("password"));
                return u;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn, stmt, rs);
        }
        return null;
    }

    public boolean register(User user) {
        try {
            conn = JdbcUtils.getConnection();
            sql = "insert into user(id, username, password, phonenum) values(null, ?, ?, ?)";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, user.getUsername());
            stmt.setString(2, user.getPassword());
            stmt.setString(3, user.getPhonenum());
            int i = stmt.executeUpdate();
            if (i > 0) {
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn, stmt, rs);
        }
        return false;
    }

    public boolean UsernameExist(User user) {
        try {
            conn = JdbcUtils.getConnection();
            sql = "select * from user where username = ?";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, user.getUsername());
            rs = stmt.executeQuery();
            if (rs.next()) {
                User u = new User();
                u.setUsername(rs.getString("username"));
                return true;// 如果用户名已被注册,则返回false
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn, stmt, rs);
        }
        return false;
    }
}

创建UserServiceInter的实现类UserServiceImpl


package service.Impl;

import service.UserServiceInter;
import bean.User;
import dao.UserDaoInter;
import dao.Impl.UserDaoImpl;

public class UserServiceImpl implements UserServiceInter {
    UserDaoInter userdao = new UserDaoImpl();

    public User login(User user) {
        return userdao.login(user);
    }

    public boolean register(User user) {
        return userdao.register(user);
    }

    public boolean UsernameExist(User user) {
        return userdao.UsernameExist(user);
    }

}
  1. 在web包下创建servlet文件

创建与login.jsp所对应的login.java文件


package web;

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 javax.servlet.http.HttpSession;

import service.UserServiceInter;
import service.Impl.UserServiceImpl;
import utils.cookieutils;
import bean.User;

public class login extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String password = request.getParameter("password");
        String username = request.getParameter("username");
        if (username == null || "".equals(username)) {
            request.setAttribute("msg1", "用户名不能为空!");
            request.getRequestDispatcher("/login.jsp").forward(request,
                    response);
            return;
        }
        if (password == null || "".equals(password)) {
            request.setAttribute("msg2", "密码不能为空!");
            request.getRequestDispatcher("/login.jsp").forward(request,
                    response);
            return;
        }
        String userimg = request.getParameter("imgcheck");
        HttpSession session = request.getSession();
        String checkcode = (String) session.getAttribute("checkcode");
        if (!userimg.equals(checkcode)) {
            request.setAttribute("msg", "请检查验证码!");
            request.getRequestDispatcher("/login.jsp").forward(request,
                    response);
            return;
        }
        String[] remember = request.getParameterValues("remember");
        Cookie[] cookiesname = request.getCookies();
        Cookie cookieusername = cookieutils.getcookies(cookiesname, "name");
        Cookie[] cookiespwd = request.getCookies();
        Cookie cookiepassword = cookieutils.getcookies(cookiespwd, "pwd");
        // 如果“记住密码”被勾选
        if (remember != null) {
            if (cookieusername != null) {
                cookieusername.setValue(username);
                cookieusername.setMaxAge(60 * 60 * 24);
                response.addCookie(cookieusername);
            } else {
                cookieusername = new Cookie("name", username);
                cookieusername.setMaxAge(60 * 60 * 24);
                response.addCookie(cookieusername);
            }
            if (cookiepassword != null) {
                cookiepassword.setValue(password);
                cookiepassword.setMaxAge(60 * 60 * 24);
                response.addCookie(cookiepassword);
            } else {
                cookiepassword = new Cookie("pwd", password);
                cookiepassword.setMaxAge(60 * 60 * 24);
                response.addCookie(cookiepassword);
            }
        } else {
            // 如果“记住密码”未被勾选
            cookieusername.setValue("");
            cookiepassword.setValue("");
            cookieusername.setMaxAge(60 * 60 * 24);
            cookiepassword.setMaxAge(60 * 60 * 24);
            response.addCookie(cookieusername);
            response.addCookie(cookiepassword);
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        UserServiceInter us = new UserServiceImpl();
        User lo = us.login(user);
        if (lo == null) {
            request.setAttribute("msg3", "用户名或密码错误,请重新输入!");
            request.getRequestDispatcher("/login.jsp").forward(request,
                    response);
        } else {
            request.getRequestDispatcher("/index.jsp").forward(request,
                    response);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置请求和响应的编码为utf-8以避免出现乱码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        doGet(request, response);
    }
}

创建与register.jsp所对应的register.java文件


package web;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

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

import service.UserServiceInter;
import service.Impl.UserServiceImpl;
import bean.User;

import com.sun.org.apache.commons.beanutils.BeanUtils;

public class register extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Map<String, String[]> map = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        UserServiceInter userservice = new UserServiceImpl();
        // 校验用户名重复
        boolean checkName = userservice.UsernameExist(user);
        if (checkName != false) {
            request.setAttribute("msg1", "用户名已存在,请登录!");
            request.getRequestDispatcher("/register.jsp").forward(request,
                    response);
            return;
        }
        // 当用户名不存在,则成功注册
        boolean regist = userservice.register(user);
        if (regist == true) {
            request.getRequestDispatcher("/login.jsp").forward(request,
                    response);
        } else {
            request.getRequestDispatcher("/register.jsp").forward(request,
                    response);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置请求和响应的编码为utf-8以避免出现乱码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        doGet(request, response);
    }
}

创建用于生成验证码图片的CheckImgServlet.java文件


package web;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/** * 生成验证码Servlet * * */
public class CheckImgServlet extends HttpServlet {

    /** * 存放的要验证的中文字幕 */
    private List<String> words = new ArrayList<String>();

    /** * 当servlet被初始化的时候,调用 */
    @Override
    public void init() throws ServletException {
        // 读取成语文件内容
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(getServletContext().getRealPath("/WEB-INF/classes/new_words.txt")),"utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                words.add(line);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

        /** * 定义了图片的宽度,和高度。 */
        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());
// 生成一个随机数,从words list中,获取文字。(要验证的内容)
        String checkcode = words.get(index);// 获得生成成员

        HttpSession session = request.getSession();
        session.setAttribute("checkcode", checkcode);

        // 定义x坐标
        int x = 10;
        for (int i = 0; i < checkcode.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 = checkcode.charAt(i);

            // 将生成汉字 加入buffer

            // 将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", checkcode);

        // 步骤五 绘制干扰线
        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();// 释放资源
        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);
    }
}

篇外:

由于水平有限,代码上可能有很多不完善的地方。记得师傅说过,“没有谁能牛逼到敢说自己的代码没有bug的地步”,所以,如果上述代码出现什么不能实现功能的地方,这里我说声抱歉。因为笔者真的还很菜。