JAVAWEB项目实现验证码中文、英文、数字组合

验证码基础

一.什么是验证码及它的作用

:验证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答.可以防止恶意破解密码、刷票、论坛灌水、有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录。

二.图文验证码的原理

:在servlet中随机生成一个指定位置的验证码,一般为四位,然后把该验证码保存到session中.在通过Java的绘图类以图片的形式输出该验证码。为了增加验证码的安全级别,可以输出图片的同时输出干扰线,最后在用户提交数据的时候,在服务器端将用户提交的验证码和Session保存的验证码进行比较。

三.验证码所需的技术

:i.因为验证码中的文字,数字,应为都是可变的,故要用到随机生成数技术。

ii.如果验证码中包含汉字,则要用到汉字生成技术.

iii.可以使用Ajax技术实现局部刷新

iv.可以使用图片的缩放和旋转技术,

vi.随机绘制干扰线(可以是折现,直线等)

vii.如果考虑到验证码的安全性,可以使用MD5加密.

中文、英文、数字组合验证码:

package randCodeImage.servlet;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.imageio.ImageIO;
/**
 * 随机生成英文、数字、中文验证图片
 *
 * @author wkr
 *
 */
public class PictureCheckCode extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public PictureCheckCode() {
        super();
    }

    public void destroy() {
        super.destroy();
    }

    public void init() throws ServletException {
        super.init();
    }
    /*该方法主要作用是获得随机生成的颜色*/
    public Color getRandColor(int s,int e){
        Random random=new Random ();
        if(s>255) s=255;
        if(e>255) e=255;
        int r,g,b;
        r=s+random.nextInt(e-s);    //随机生成RGB颜色中的r值
        g=s+random.nextInt(e-s);    //随机生成RGB颜色中的g值
        b=s+random.nextInt(e-s);    //随机生成RGB颜色中的b值
        return new Color(r,g,b);
    }

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //设置不缓存图片
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "No-cache");
        response.setDateHeader("Expires", 0);
//        request.setCharacterEncoding("UTF-8");
//        request.setCharacterEncoding("UTF-8");
//        response.setContentType("text/html;charset=UTF-8");
        //指定生成的响应图片,一定不能缺少这句话,否则错误.
        response.setContentType("image/jpeg");
        int width=86,height=32;        //指定生成验证码的宽度和高度
        BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);    //创建BufferedImage对象,其作用相当于一图片
        Graphics g=image.getGraphics();        //创建Graphics对象,其作用相当于画笔
        Graphics2D g2d=(Graphics2D)g;        //创建Grapchics2D对象
        Random random=new Random();
        Font mfont=new Font("楷体",Font.BOLD,24);    //定义字体样式
        g.setColor(getRandColor(200,250));
        g.fillRect(0, 0, width, height);    //绘制背景
        g.setFont(mfont);                    //设置字体
        g.setColor(getRandColor(180,200));

        //绘制100条颜色和位置全部为随机产生的线条,该线条为2f
        for(int i=0;i<100;i++){
            int x=random.nextInt(width-1);
            int y=random.nextInt(height-1);
            int x1=random.nextInt(6)+1;
            int y1=random.nextInt(12)+1;
            BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);    //定制线条样式
            Line2D line=new Line2D.Double(x,y,x+x1,y+y1);
            g2d.setStroke(bs);
            g2d.draw(line);        //绘制直线
        }
        //输出由英文,数字,和中文随机组成的验证文字,具体的组合方式根据生成随机数确定。
        String sRand="";
        String ctmp="";
        int itmp=0;
        //制定输出的验证码为四位
        for(int i=0;i<4;i++){
            switch(random.nextInt(3)){
                case 1:        //生成A-Z的字母
                     itmp=random.nextInt(26)+65;
                     ctmp=String.valueOf((char)itmp);
                     break;
                case 2:        //生成汉字
                     String[] rBase={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
                     //生成第一位区码
                     int r1=random.nextInt(3)+11;
                     String str_r1=rBase[r1];
                     //生成第二位区码
                     int r2;
                     if(r1==13){
                         r2=random.nextInt(7);
                     }else{
                         r2=random.nextInt(16);
                     }
                     String str_r2=rBase[r2];
                     //生成第一位位码
                     int r3=random.nextInt(6)+10;
                     String str_r3=rBase[r3];
                     //生成第二位位码
                     int r4;
                     if(r3==10){
                         r4=random.nextInt(15)+1;
                     }else if(r3==15){
                         r4=random.nextInt(15);
                     }else{
                         r4=random.nextInt(16);
                     }
                     String str_r4=rBase[r4];
                     //将生成的机内码转换为汉字
                     byte[] bytes=new byte[2];
                     //将生成的区码保存到字节数组的第一个元素中
                     String str_12=str_r1+str_r2;
                     int tempLow=Integer.parseInt(str_12, 16);
                     bytes[0]=(byte) tempLow;
                     //将生成的位码保存到字节数组的第二个元素中
                     String str_34=str_r3+str_r4;
                     int tempHigh=Integer.parseInt(str_34, 16);
                     bytes[1]=(byte)tempHigh;
                     ctmp=new String(bytes,"GB2312");
                     break;
                default:
                     itmp=random.nextInt(10)+48;
                     ctmp=String.valueOf((char)itmp);
                     break;
            }
            sRand+=ctmp;
            Color color=new Color(20+random.nextInt(110),20+random.nextInt(110),random.nextInt(110));
            g.setColor(color);
            //将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示
            /*将文字旋转制定角度*/
            Graphics2D g2d_word=(Graphics2D)g;
            AffineTransform trans=new AffineTransform();
            trans.rotate((45)*3.14/180,15*i+8,7);
            /*缩放文字*/
            float scaleSize=random.nextFloat()+0.8f;
            if(scaleSize>1f) scaleSize=1f;
            trans.scale(scaleSize, scaleSize);
            g2d_word.setTransform(trans);
            g.drawString(ctmp, 15*i+18, 14);
        }
        System.out.println("验证码:>>>"+sRand);
        HttpSession session=request.getSession(true);
        session.setAttribute("randCheckCode", sRand);
        g.dispose();    //释放g所占用的系统资源
        ImageIO.write(image,"JPEG",response.getOutputStream());    //输出图片
    }
}

英文、数字组合验证码(附加读取配置文件):

package randCodeImage.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
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 randCodeImage.util.ResourceUtil;

//import com.sun.image.codec.jpeg.JPEGCodec;
//import com.sun.image.codec.jpeg.JPEGEncodeParam;
//import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 随机生成英文、数字验证图片
 *
 * @author wkr
 *
 */
public class RandCodeImageServlet extends HttpServlet {
    private static final long serialVersionUID = -1257947018545327308L;
    private static final String SESSION_KEY_OF_RAND_CODE = "randCode"; // todo 要统一常量
    /**
     *
     */
    private static final int count = 200;

    /**
     * 定义图形大小
     */
    private static final int width = 105;
    /**
     * 定义图形大小
     */
    private static final int height = 35;
    // private Font mFont = new Font("Arial Black", Font.PLAIN, 15); //设置字体
    /**
     * 干扰线的长度=1.414*lineWidth
     */
    private static final int lineWidth = 2;

    @Override
    public void doGet(final HttpServletRequest request,
            final HttpServletResponse response) throws ServletException,
            IOException {
        // 设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // response.setContentType("image/png");

        // 在内存中创建图象
        final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        final Graphics2D graphics = (Graphics2D) image.getGraphics();

        // 设定背景颜色
        graphics.setColor(Color.WHITE); // ---1
        graphics.fillRect(0, 0, width, height);
        // 设定边框颜色
//        graphics.setColor(getRandColor(100, 200)); // ---2
        graphics.drawRect(0, 0, width - 1, height - 1);

        final Random random = new Random();
        // 随机产生干扰线,使图象中的认证码不易被其它程序探测到
        for (int i = 0; i < count; i++) {
            graphics.setColor(getRandColor(150, 200)); // ---3

            final int x = random.nextInt(width - lineWidth - 1) + 1; // 保证画在边框之内
            final int y = random.nextInt(height - lineWidth - 1) + 1;
            final int xl = random.nextInt(lineWidth);
            final int yl = random.nextInt(lineWidth);
            graphics.drawLine(x, y, x + xl, y + yl);
        }

        // 取随机产生的认证码(4位数字)
        final String resultCode = exctractRandCode();
        for (int i = 0; i < resultCode.length(); i++) {
            // 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            // graphics.setColor(new Color(20 + random.nextInt(130), 20 + random
            // .nextInt(130), 20 + random.nextInt(130)));

            // 设置字体颜色
            graphics.setColor(Color.BLACK);
            // 设置字体样式
//            graphics.setFont(new Font("Arial Black", Font.ITALIC, 18));
            graphics.setFont(new Font("Times New Roman", Font.BOLD, 24));
            // 设置字符,字符间距,上边距
            graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26);
        }

        // 将认证码存入SESSION
        request.getSession().setAttribute(SESSION_KEY_OF_RAND_CODE, resultCode);
        // 图象生效
        graphics.dispose();

        // 输出图象到页面
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }

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

    /**
     * @return 随机码
     */
    private String exctractRandCode() {
        final String randCodeType = ResourceUtil.getRandCodeType();
        int randCodeLength = Integer.parseInt(ResourceUtil.getRandCodeLength());
        if (randCodeType == null) {
            return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
        } else {
            switch (randCodeType.charAt(0)) {
            case ‘1‘:
                return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
            case ‘2‘:
                return RandCodeImageEnum.LOWER_CHAR.generateStr(randCodeLength);
            case ‘3‘:
                return RandCodeImageEnum.UPPER_CHAR.generateStr(randCodeLength);
            case ‘4‘:
                return RandCodeImageEnum.LETTER_CHAR.generateStr(randCodeLength);
            case ‘5‘:
                return RandCodeImageEnum.ALL_CHAR.generateStr(randCodeLength);

            default:
                return RandCodeImageEnum.NUMBER_CHAR.generateStr(randCodeLength);
            }
        }
    }

    /**
     * 描述:
     *
     * @param fc
     *            描述:
     * @param bc
     *            描述:
     *
     * @return 描述:
     */
    private Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色
        final Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }

        final int r = fc + random.nextInt(bc - fc);
        final int g = fc + random.nextInt(bc - fc);
        final int b = fc + random.nextInt(bc - fc);

        return new Color(r, g, b);
    }
}

/**
 * 验证码辅助类
 *
 * @author 张国明 [email protected] <br/>
 *         2012-2-28 下午2:15:14
 *
 */
enum RandCodeImageEnum {
    /**
     * 混合字符串
     */
    ALL_CHAR("123456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"),
    /**
     * 字符
     */
    LETTER_CHAR("abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"),
    /**
     * 小写字母
     */
    LOWER_CHAR("abcdefghjkmnpqrstuvwxyz"),
    /**
     * 数字
     */
    NUMBER_CHAR("123456789"),
    /**
     * 大写字符
     */
    UPPER_CHAR("ABCDEFGHJKMNPQRSTUVWXYZ");
    /**
     * 待生成的字符串
     */
    private String charStr;

    /**
     * @param charStr
     */
    private RandCodeImageEnum(final String charStr) {
        this.charStr = charStr;
    }

    /**
     * 生产随机验证码
     *
     * @param codeLength
     *            验证码的长度
     * @return 验证码
     */
    public String generateStr(final int codeLength) {
        final StringBuffer sb = new StringBuffer();
        final Random random = new Random();
        final String sourseStr = getCharStr();

        for (int i = 0; i < codeLength; i++) {
            sb.append(sourseStr.charAt(random.nextInt(sourseStr.length())));
        }

        return sb.toString();
    }

    /**
     * @return the {@link #charStr}
     */
    public String getCharStr() {
        return charStr;
    }

}

读取配置文件工具类:

package randCodeImage.util;

import java.util.ResourceBundle;
//commons-lang-2.6.jar
import org.apache.commons.lang.StringUtils;

/**
 * 项目参数工具类
 * @author otowa
 *
 */
public class ResourceUtil {

    //获得指定的环境变量的值env若获取不到,由默认值pro代替
    private static final String env = StringUtils.defaultIfBlank(System.getProperty("env"), StringUtils.defaultIfBlank(System.getenv("env"), "pro"));

    private static final ResourceBundle sysConfig = java.util.ResourceBundle.getBundle(env+"/sysConfig");

    /**
     * 获取随机码的长度
     *
     * @return 随机码的长度
     */
    public static String getRandCodeLength() {
        return sysConfig.getString("randCodeLength");
    }
    /**
     * 获取随机码的类型
     *
     * @return 随机码的类型
     */
    public static String getRandCodeType() {
        return sysConfig.getString("randCodeType");
    }
}

sysConfig.properties配置文件(路径:/resources/dev/sysConfig.properties):

#随机码的长度
randCodeLength=4
#随机码的类型
randCodeType=5

验证码jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">

    /**
     * 异步刷新验证码
     */
    $(‘#randCodeImage‘).click(function(){
        reloadRandCodeImage();
    });
    function reloadRandCodeImage() {
        var date = new Date();
        var img = document.getElementById("randCodeImage");
        img.src=‘randCodeImageServlet?a=‘ + date.getTime();
    }
</script>
<script language="javascript">
    /**
     * 异步刷新验证码
     */
    function myReload() {
        document.getElementById("CreateCheckCode").src = document
                .getElementById("CreateCheckCode").src
                + "?nocache=" + new Date().getTime();
    }
</script>
</head>
<body>
    <form action="">
        英文、数字验证码:
        <input type="text" name="code" size="4" >
        <img id="randCodeImage" alt="验证码" src="randCodeImageServlet">
        <a id="verifyChange" href="javascript:void(0);" onclick="reloadRandCodeImage();" >换一张</a>
    </form>

    <form action="page/randCodeImage/Check.jsp" method="post">
        中文、英文、数字验证码:
        <input name="checkCode" type="text" id="checkCode" title="验证码区分大小写"
            size="8" maxlength="4" />
        <img src="PictureCheckCode" id="CreateCheckCode" align="middle">
        <a href="javascript:;" onclick="myReload()"> 看不清,换一个</a>
        <input type="submit" value="提交" />
    </form>
</body>
</html>

提交效验jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page language="java" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>验证码校验</title>
</head>
<body>
 <%
         request.setCharacterEncoding("utf-8");
        String checkcode=request.getParameter("checkCode");
         out.print("<script>alert(‘提交内容:"+checkcode+"‘);</script>");
        if(checkcode.equals("")||checkcode==null){
            out.print("<script>alert(‘请输入验证码‘);window.location.href(‘index.jsp‘)</script>");
        }else{
            if(!checkcode.equalsIgnoreCase((String)session.getAttribute("randCheckCode"))){
                out.print("<script>alert(‘验证码不正确,请重新输入‘);history.back(-1);</script>");
            }else{
                out.print("登录成功");
            }
        }
     %>
</body>
</html>

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <!-- 随机生成验证码图片 -->
  <servlet>
    <description>输出验证码</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>PictureCheckCode</servlet-name>
    <servlet-class>randCodeImage.servlet.PictureCheckCode</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>RandCodeImageServlet</servlet-name>
    <servlet-class>randCodeImage.servlet.RandCodeImageServlet</servlet-class>
  </servlet>

  <!-- 随机生成验证码图片 -->
  <servlet-mapping>
    <servlet-name>PictureCheckCode</servlet-name>
    <url-pattern>/PictureCheckCode</url-pattern>
  </servlet-mapping> 
  <servlet-mapping>
    <servlet-name>RandCodeImageServlet</servlet-name>
    <url-pattern>/randCodeImageServlet</url-pattern>
  </servlet-mapping> 

  <!-- 拦路虎 -->
  <display-name>sdfsdf</display-name>
  <welcome-file-list>
    <!-- 随机生成验证码图片 -->
    <welcome-file>page/randCodeImage/login.jsp</welcome-file>
  </welcome-file-list>
</web-app>

页面效果:

本文参考:程序员形同陌路

时间: 2024-10-25 12:47:08

JAVAWEB项目实现验证码中文、英文、数字组合的相关文章

JavaScript控制输入框中只能输入中文、数字和英文

1.问题背景 遇到这样一个问题:有一个输入框,要求只能输入中文.数字和英文(即过滤特殊字符串) 2.JS代码 function  checkUsername() { //正则表达式 var reg = new RegExp("^[a-zA-Z\d\u4E00-\u9FA5]+$"); //获取输入框中的值 var username = document.getElementById("username").value.trim(); //判断输入框中有内容 if(u

Java学习(4):统计一个文件中的英文,中文,数字,其他字符以及字符总数

要求:统计一个文件中的英文,中文,数字,其他字符以及字符总数(此随笔以txt文件为例) import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; /** * 将一个文件中英文,中文,数字,其

Oracle中中文、数字,英文混杂形式的字段进行排序的方法

http://blog.csdn.net/p451933505/article/details/9272257 对Oracle中中文.数字.英文混杂形式的字段进行排序的方法: 例如: order by NLSSORT(字段名,'NLS_SORT = SCHINESE_PINYIN_M'), to_number(translate(字段名, '0123456789' || 字段名, '0123456789')) NLSSORT() 函数: 可以使用NLSSORT()函数可以改变Oralce 对汉字

分享《TensorFlow机器学习项目实战》中文PDF+英文PDF+源代码

下载:https://pan.baidu.com/s/1U3OiYNhS9ncvzpHGMoZfjA 更多资料分享:http://blog.51cto.com/3215120 <TensorFlow机器学习项目实战>中文PDF+英文PDF+源代码中文PDF,331页,带书签目录,文字可以复制,彩色配图.英文PDF,367页,带书签目录,文字可以复制,彩色配图.中英文两版对比学习.配套源代码. 作者: [阿根廷]Rodolfo Bonnin 译者: 姚鹏鹏 本书主要介绍如何使用TensorFlo

JavaEE——Intellij Idea 创建JavaWeb项目

原文:JavaEE--Intellij Idea 创建JavaWeb项目 折腾Tomcat折腾了两个晚上,第一个晚上怎么都进不了Tomcat的首页,第二个晚上进去了,但是新建的Web项目,在浏览器中运行,总是 Error on Apache Tomcat: The requested resource is not available  坑爹!!!!. 首先我要说一点,在IntelliJ IDEA里面“new Project”就相当于我们eclipse的“workspace”,而“new Mod

SQL按指定文字顺序进行排序(中文或数字等)

在有些情况下我们需要按指定顺序输出数据,比如选择了ID in(3,1,2,5,4)我们希望按这个3,1,2,5,4的顺序输出,这样只使用order by ID是无法实现的, 但是我们可以使用order by charindex(','+convert(varchar,ID)+',',',3,1,2,5,4,')的方法来实现这个目的.举例如下: Create Table info( ID int identity(1,1) not null, title varchar(100) not null

关联分析FPGrowth算法在JavaWeb项目中的应用

关联分析(关联挖掘)是指在交易数据.关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式.关联.相关性或因果结构.关联分析的一个典型例子是购物篮分析.通过发现顾客放入购物篮中不同商品之间的联系,分析顾客的购买习惯.比如,67%的顾客在购买尿布的同时也会购买啤酒.通过了解哪些商品频繁地被顾客同时购买,可以帮助零售商制定营销策略.分析结果可以应用于商品货架布局.货存安排以及根据购买模式对顾客进行分类. FPGrowth算法是韩嘉炜等人在2000年提出的关联分析算法,在算法中使用了一种

手把手教你做JavaWeb项目:登录模块

现如今,无论是客户端还是移动端,无论是游戏登陆还是社交平台登陆,无处不在的“登陆”.那么你知道怎么制作吗?今天就为你娓娓道来: 用户登录 在各大信息管理系统中,登录功能是必不可少的,他的作用就是验证用户的身份,判断用户是否是本站的会员,只有会员才能访问当前系统 登录的实现步骤: 1.用户填写账号和密码,提交到后台2.后台获取到账号和密码后,将其发送到数据库中进行查询3.查询结果如果为null,说明用户填写的账号或者密码有误,应该回到登录页面并提示用户重新输入4.查询结果如果不为null,说明用户

第一个远程javaweb项目测试全过程

2017-5-20,在这个奇特的日子,我不再满足于在本地测试javaweb,于是在上腾讯云买了第一个云服务器,由于是学生认证,所以一个月只要10块钱,还是要抢的,每天早上9点开抢 打开后,发现其实是一个云主机,就是远程主机,只不过他可以给你一个公网ID,就是在浏览器输入公网ID的话,全国所有人都可以访问你的项目 关于怎么把自己的javaweb项目放到云主机,有一个教程http://www.cnblogs.com/diyunfei/p/6826557.html,前提是得先在云主机下载配置jkd,t