zoukankan      html  css  js  c++  java
  • Java Web 开发进阶案例之人事管理系统的完整实现

    技术:Java+ jsp + servlet+ javabeans +sql+tomcat
     

    概述

    本系统的主要任务是实现人事管理系统的系统化和自动化管理, 主要包括招聘入 职、到期离职和员工调动信息管理等功能。具体完成的功能如下: 员工信息管理:员工信息查询、员工入职登记,员工信息更改、删除等 员工调动管理:员工调动登记、员工调动记录查询,员工调动信息更改、删除等 银行账户管理: 公司银行账户管理:公司银行账户登记和公司银行账户信息更改。 员工银行账户管理:员工银行账户登记、员工银行账户更改和删除等 公司信息管理: 职位类别管理:职位类别添加、职位类别信息更改、删除等 部门信息管理:部门类别添加、部门信息更改、删除等 系统管理: 登录密码修改模块 管理员管理模块:管理员添加、管理员信息更改和管理员删除等 系统帮助:关于使用该系统的一些帮助文档信息。 MyEclipse 8.5 +java+jsp + servlet+ javabeans + tomcat

    详细

    一、概述
    本系统的主要任务是实现人事管理系统的系统化和自动化管理, 主要包括招聘入
    职、到期离职和员工调动信息管理等功能。具体完成的功能如下:
    员工信息管理:员工信息查询、员工入职登记,员工信息更改、删除等
    员工调动管理:员工调动登记、员工调动记录查询,员工调动信息更改、删除等
    银行账户管理:
    公司银行账户管理:公司银行账户登记和公司银行账户信息更改。
    员工银行账户管理:员工银行账户登记、员工银行账户更改和删除等
    公司信息管理:
    职位类别管理:职位类别添加、职位类别信息更改、删除等
    部门信息管理:部门类别添加、部门信息更改、删除等
    系统管理:
    登录密码修改模块
    管理员管理模块:管理员添加、管理员信息更改和管理员删除等
    系统帮助:关于使用该系统的一些帮助文档信息。

    二、 开发平台与环境

    本系统是 基于 B/S 平台的系统,利用 jsp + servlet+ javabeans 技术,基于 MVC 三层模式,
    开发工具使用 MyEclipse 8.5 集成开发环境,数据库管理工具 SQL Server 2005 等。

    三、系统的分析、设计与实现
    1 系统分析:
    (1) 角色分析:由于该系统属于典型的 MIS 管理系统,系统主要使用对象是管理员,分
    为两类普通管理员和系统管理员;普通管理员只具有一般的查看、查询和检索权限;
    系统管理员除了普通管理员所具有的权限外,还有高级权限:对所有信息做出更改,
    删除等权限功能。
    (2) 用例分析:根据用例分析所得到如下系统用例图:
    2 系统设计:
    2.1 数据库设计:
    根据系统的分析与设计,如下设计数据库的数据表和数据结构:
    2.1.1 逻辑表设计:
    管理员表: id,登录名,登录密码,管理员类型号
    管理员类型表: id,管理员类型号,管理员类型
    员工基本信息表: id,员工编号,姓名,性别,出生日期,职位,部门,工资,入职时
    间,身份证号
    职位类别表: id,岗位编号,岗位名称,岗位工资
    部门信息表: id,部门编号,部门名称,部门职能,部门领导
    职位设置表: id,部门编号,岗位编号)
    员工调动表: id,职工编号,原职位,调任职位,原部门编号,调任部门编号,性质,备

    公司基本信息表: id,公司名称,公司性质,法人代表,公司地址,电话,邮箱:
    公司银行账户表: id,银行账号,银行账户类型,开户行,备注:
    员工银行账户表: id,员工编号,银行账号,银行账户,开户行,备注:
    2.1.2 数据字典设计:
    数据字典:
    管理员表(admins)

    字段

    类型

    备注

    id

    Int

    主键,自增

    aName

    Nvarchar(20)

    管理员登录名

    aPwd

    Nvarchar(20)

    管理员登陆密码

    aTypeId

    Int

    管理员类型号


    管理员类型表(admintype)

    字段

    类型

    备注

    id

    Int

    主键,自增

    aTypeId

    Nvarchar(20)

    管理员类型

    aTypeName

    Nvarchar(20)

    管理员类型名称


    员工基本信息表(staff)

    字段

    类型

    备注

    id

    Int

    主键,自增

    sId

    Nvarchar(14)

    员工编号

    sName

    Nvarchar(20)

    员工姓名

    sSex

    Nvarchar(2)

    员工性别

    sBirthday

    Datetime

    出生日期

    sPost

    Nvarchar(20)

    职位,岗位

    sDepartment

    Nvarchar(20)

    部门

    sSalary

    Int

    工资

    sEntry

    Datetime

    入职时间

    sIdentityId

    Nvarchar(20)

    身份证号



    职位类别表(postcategory)

    字段

    类型

    备注

    id

    Int

    主键,自增

    pId

    Nvarchar(20)

    职位编号

    pName

    Nvarchar(20)

    职位名称

    pSalary

    int

    职位工资


    部门信息表(department)

    字段

    类型

    备注

    id

    Int

    主键,自增

    dId

    Nvarchar(20)

    部门编号

    dName

    Nvarchar(20)

    部门名称

    dFunction

    Text

    部门职能

    dLeader

    Nvarchar(20)

    部门领导(经理)


    职位设置表(postsetting)

    字段

    类型

    备注

    id

    Int

    主键,自增

    pId

    Nvarchar(20)

    职位编号

    dId

    Nvarchar(20)

    部门编号


    员工调动表(staffchange)

    字段

    类型

    备注

    id

    Int

    主键,自增

    sId

    Nvarchar(10)

    员工编号

    pIdOld

    Nvarchar(20)

    原职位编号

    pIdNew

    Nvarchar(20)

    调任职位编号

    dIdOld

    Nvarchar(20)

    原部门编号

    dIdNew

    Nvarchar(20)

    调任部门编号

    sNature

    Nvarchar(20)

    性质(长期或短期)

    sRemark

    Text

    备注


    公司基本信息表(company)

    字段

    类型

    备注

    id

    Int

    主键

    cName

    Nvarchar(50)

    公司名称

    cNature

    Nvarchar(20)

    公司性质

    cLegalPerson

    Nvarchar(20)

    法人代表

    cAddress

    Nvarchar(100)

    公司地址

    cTel

    Nvarchar(20)

    电话

    cEmail

    Nvarchar(40)

    邮箱


    公司银行账户表(companybank)

    字段

    类型

    备注

    id

    Int

    主键

    bId

    Nvarchar(30)

    银行账号

    cBankType

    Nvarchar(20)

    银行账户类型

    cBankName

    Nvarchar(60)

    开户行

    cRemark

    Text

    备注


    员工银行账户表(staffbank)

    字段

    类型

    备注

    id

    Int

    主键,自增

    sId

    Nvarchar(20)

    员工编号

    bId

    Nvarchar(30)

    银行账号

    cBankType

    Nvarchar(20)

    银行账户类型

    cBankName

    Nvarchar(60)

    开户行

    cRemark

    Text

    备注


    2.2 系统设计思想
    (1)系统界面设计
    由于该系统是个典型的 MIS 管理系统,本系统采用框架页面设计模式。常用
    的头部和尾巴设计成单独模块,提高开发效率,提高模块重用性,方便系统升级。
    (2)系统架构模式
    本系统采用的是基于 Web 的 Java EE MVC 三层架构模式。
    三层架构模式的原理图如下:

    而将 MVC 三层模式应用于 Java EE 中,就是基于 JSP+Servlet+javabeans,其中, JSP 是视图,
    servlet 是控制器,而 javabeans 则是模型。原理图如下:

    3 系统实现:
    (1)公用模块:
    Commons Dbutils jar 包:该包是 apache 开发的一个用来常用操作的工具包。
    字节编码过滤功能:该模块是使用过滤器技术对所有 servlet 编码设置进行过滤,主要用来解
    决 jsp 中汉字问题。核心代码如下:

    public class CharacterEncodingFilter implements Filter {
    private FilterConfig config ;
    private String encoding="ISO-8859-1";
    public void destroy() {
    // TODO Auto-generated method stub
    config = null;
    }
    public void doFilter(ServletRequest request, ServletResponse
    response,
    FilterChain chain) throws IOException, ServletException {
    // TODO Auto-generated method stub
    request.setCharacterEncoding(encoding);
    chain.doFilter(request, response);
    }
    public void init(FilterConfig config) throws ServletException {
    // TODO Auto-generated method stub
    this.config = config;
    String s = config.getInitParameter("encoding");
    if(s!=null){
    encoding = s;
    }
    }
    }

    Tomcat 数据库连接池技术:本系统采用 tomcat 数据池技术,便于数据库的配置和访问。 具
    体配置是在 tomcat 安装目录下的 conf 文件下的 context.xml 文件中添加如下代码:

    <Resource name="jdbc/permanageds"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive = "100"
    maxIdle="30"
    maxWait="10000"
    username="sa"
    password="caizhiming"
    driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    url="jdbc:sqlserver://localhost:1433;DatabaseName=permanage"
    />

    SQL 数据库操作工具类:该类主要用来处理与数据库相关的操作,核心代码如下:

    public class SqlDbUtil {
    private String dataSourceName;
    private DataSource ds;
    public SqlDbUtil() {
    // TODO Auto-generated constructor stub
    }
    public SqlDbUtil(String dataSourceName){
    this.dataSourceName = dataSourceName;
    }
    public void setDataSourceName(String dataSourceName) {
    this.dataSourceName = dataSourceName;
    }
    public void setDs(DataSource ds) {
    this.ds = ds;
    }
    //初始化数据源
    public void init(){
    try {
    Context initContext = new InitialContext();
    this.ds = (DataSource)initContext.lookup(dataSourceName);
    initContext.close();
    } catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    //更新数据库语句,结果返回int类型
    public int update(String sql,String[] params){
    QueryRunner qr = new QueryRunner(ds);
    int result = 0;
    try {
    if(params!=null)
    result = qr.update(sql, params);
    else {
    result = qr.update(sql);
    }
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return result;
    }
    //更新数据库语句,结果返回为Object类型,创建javabeans类型时用
    public Object query(String sql,String[] params,ResultSetHandler
    rsh){
    QueryRunner qr = new QueryRunner(ds);
    Object results = null;
    try {
    results=qr.query(sql, params, rsh);
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return results;
    }
    }

    字符串工具类: 该类主要用类处理一些字符串相关操作等所用到的工具方法,相关核心代码
    如下:

    public class StringUtil {
    //验证字符串是否为空
    public static boolean validateNull(String s){
    if(s==null || s.length()==0)
    return true;
    else {
    return false;
    }
    }
    //改变空字符串
    public static String changeNull(String source,String target){
    if(source==null || source.length()==0 ||
    source.equalsIgnoreCase("null"))
    return target;
    else {
    return source;
    }
    }
    //过滤 html标记符
    public static String filterHtml(String s){
    if(s==null)
    return null;
    if(s.length()==0)
    return s;
    s.replaceAll("&", "&");
    s.replaceAll("<", "<");
    s.replaceAll(">", ">");
    s.replaceAll(" ", " ");
    s.replaceAll("'", "';");
    s.replaceAll(""", """);
    s.replaceAll("
    ", "<br/>");
    return s;
    }
    }

    (2) 系统登录模块实现: 该模块是系统的使用入口,通过该入口进入系统。 登录验证采用
    Session 验证机制。
    核心代码如下:

    String path =request.getContextPath();
    request.setCharacterEncoding("utf-8");
    int typeId = 1;
    String name = request.getParameter("name").trim();
    String pwd = request.getParameter("pwd");
    String type = request.getParameter("type");
    if(type.equalsIgnoreCase("普通管理员"))
    typeId = 0;
    String strCmd ="select * from admins where aName='"+name+"' and
    aPwd='"+pwd+"' and aTypeId='"+typeId+"' ";
    SqlDbUtil dbUtil = new
    SqlDbUtil("java:/comp/env/jdbc/permanageds");
    dbUtil.init();
    List list = (List)dbUtil.query(strCmd, null, new
    BeanListHandler(Admins.class));
    if(list.size()!=0){
    HttpSession session = request.getSession();
    Admins ad = (Admins)list.get(0);
    session.setAttribute("aId", ad.getId());
    session.setAttribute("name", name);
    session.setAttribute("type", type);
    response.sendRedirect(path+"/index.jsp");
    }
    else {
    response.sendRedirect(path+"/login.jsp");
    request.setAttribute("msg", "用户名或密码错误,请重新登录!");
    }

    登录界面如下:

    (3) 员工信息管理模块实现
    该模块主要有员工信息查询、入职登记以及修改删除等。
    员工信息查询主要是通过搜索检索查询员工的信息,查询结果分页形式显示出来,
    具体核心代码如下:

    String text = "%"+request.getParameter("search").trim()+"%";
    String type = request.getParameter("type").trim();
    SqlDbUtil dbUtil = new
    SqlDbUtil("java:/comp/env/jdbc/permanageds");
    dbUtil.init();
    //每页显示记录数
    int PageSize =8;
    int StartRow = 0; //开始显示记录的编号
    int PageNo = 0;//需要显示的页数
    int CounterStart = 0;//每页页码的初始值
    int CounterEnd = 0;//显示页码的最大值
    int RecordCount = 0;//总记录数;
    int MaxPage = 0;//总页数
    int PrevStart = 0;//前一页
    int NextPage = 0;//下一页
    int LastRec = 0;
    //int LastStartRecord = 0;//最后一页开始显示记录的编号
    //获取需要显示的页数,由用户提交
    if (request.getParameter("page") == null) { //如果为空,则表示第1
    页
    if (StartRow == 0) {
    PageNo = StartRow + 1; //设定为1
    }
    } else {
    PageNo = Integer.parseInt(request.getParameter("page")); //
    获得用户提交的页数
    StartRow = (PageNo - 1) * PageSize; //获得开始显示的记录编号
    }
    //因为显示页码的数量是动态变化的,假如总共有一百页,则不可能同时显示100个链
    接。而是根据当前的页数显示
    //一定数量的页面链接
    //设置显示页码的初始值!!
    if (PageNo % PageSize == 0) {
    CounterStart = PageNo - (PageSize - 1);
    } else {
    CounterStart = PageNo - (PageNo % PageSize) + 1;
    }
    CounterEnd = CounterStart + (PageSize - 1);
    String strSql1 = null;
    if(type.equals("sId"))
    strSql1 = "select * from staff where sId like '"+text+"'";
    if(type.equals("sName"))
    strSql1 = "select * from staff where sName like '" +text+ "'";
    if(text.isEmpty())
    strSql1 = "select * from staff ";
    List list = (List) dbUtil.query(strSql1, null, new
    BeanListHandler(Staff.class));
    RecordCount = list.size();
    //取特定页数的数据
    String strColumn = " * ";
    String strTable = " staff ";
    String strSort = " id desc ";
    String PKID = "id";
    String strSql2 = "";
    String strWhere = "where " + type +" like "+ "'"+text+"'" ;
    String START_ID = Integer.toString((PageNo - 1) * PageSize + 1);
    String END_ID = Integer.toString(PageNo * PageSize);
    strSql2 = " SELECT " + strColumn
    + " FROM (SELECT ROW_NUMBER() OVER(ORDER BY " + strSort
    + ") AS rownum," + strColumn + " FROM " + strTable
    + " WITH(NOLOCK) " + strWhere
    + ") AS D WHERE rownum BETWEEN " + START_ID + " AND "
    + END_ID + " ORDER BY " + strSort;
    //获取总页数
    MaxPage = RecordCount % PageSize;
    if (RecordCount % PageSize == 0) {
    MaxPage = RecordCount / PageSize;
    }
    else {
    MaxPage = RecordCount / PageSize + 1;
    }
    List list2 = (List) dbUtil.query(strSql2, null, new
    BeanListHandler(Staff.class));
    request.setAttribute("staff", list2);
    request.setAttribute("PageSize", PageSize);
    request.setAttribute("StartRow", StartRow);
    request.setAttribute("PageNo", PageNo);
    request.setAttribute("CounterStart", CounterStart);
    request.setAttribute("CounterEnd", CounterEnd);
    request.setAttribute("RecordCount", RecordCount);
    request.setAttribute("MaxPage", MaxPage);
    request.setAttribute("PrevStart", PrevStart);
    request.setAttribute("NextPage", NextPage);
    request.setAttribute("LastRec", LastRec);
    request.getRequestDispatcher("/staff/staffsearch.jsp").forward(re
    quest, response);

    系统主界面如下:

    入职登记是登记新入职员工信息,具体核心代码如下:

    String path = request.getContextPath();
    int result = 0;
    String sId = null;
    String sName = request.getParameter("sName").trim();
    String sSex = request.getParameter("sSex").trim();
    String
    birth=request.getParameter("birthyear")+"-"+request.getParameter("bir
    thmon");
    birth+="-"+request.getParameter("birthday");
    String job =
    request.getParameter("jobyear")+"-"+request.getParameter("jobmon");
    job += "-"+request.getParameter("jobday");
    Date birthDate =null;
    Date jobDate = null;
    Date sIdDate=null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    SimpleDateFormat sdf2=new SimpleDateFormat("yyyyMMddHHmmss");
    try {
    birthDate = sdf.parse(birth);
    jobDate = sdf.parse(job);
    sId = sdf2.format(new java.util.Date());
    } catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    String pId = request.getParameter("sPost").trim();// 获取的是职位
    对应的职位编号
    String sSalary = request.getParameter("sSalary").trim();
    String sIdentityId =
    request.getParameter("sIdentityId").trim();
    SqlDbUtil db = new SqlDbUtil("java:/comp/env/jdbc/permanageds");
    db.init();
    String strCmd2 = "select * from postsetting where pId ='" + pId
    + "'";
    List list2 = (List) db.query(strCmd2, null, new
    BeanListHandler(Postsetting.class));
    Postsetting ps = (Postsetting) list2.get(0);
    String dId = ps.getdId();
    String strCmd4 = "select * from postcategory where pId ='" + pId
    + "'";
    List list4 = (List) db.query(strCmd4, null, new
    BeanListHandler(Postcategory.class));
    Postcategory pc = (Postcategory) list4.get(0);
    String sPost =pc.getpName();
    String strCmd3 = "select * from department where dId ='" + dId +
    "'";
    List list3 = (List) db.query(strCmd3, null, new
    BeanListHandler(Department.class));
    Department dt = (Department) list3.get(0);
    String sDepartment = dt.getdName();// 获取到职位所隶属的部门名称
    String strCmd = "insert into staff
    (sId,sName,sSex,sBirthday,sPost,sDepartment,sSalary,sEntry,sIdentityI
    d) values(?,?,?,?,?,?,?,?,?)";
    String[] params = { sId, sName, sSex, sdf.format(birthDate),
    sPost,sDepartment, sSalary, sdf.format(jobDate), sIdentityId };
    for(int i=0;i<100000;i++){
    result = db.update(strCmd, params);
    }
    if (result == 0) {
    String message = "对不起,内容更新失败,请重新更新! <br/>";
    request.getRequestDispatcher("/company/addpostcategory.jsp")
    .forward(request, response);
    } else {
    response.sendRedirect(path + "/servlet/manageStaff");
    }

    员工信息管理主要是负责员工信息的修改和删除功能。
    信息修改的核心代码如下:

    String path = request.getContextPath();
    int result = 0;
    request.setCharacterEncoding("utf-8");
    String sName = request.getParameter("sName").trim();
    String sSex = request.getParameter("sSex").trim();
    String
    birth=request.getParameter("birthyear")+"-"+request.getParameter("bir
    thmon");
    birth+="-"+request.getParameter("birthday");
    String job =
    request.getParameter("jobyear")+"-"+request.getParameter("jobmon");
    job += "-"+request.getParameter("jobday");
    Date birthDate =null;
    Date jobDate = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    try {
    try {
    birthDate = sdf.parse(birth);
    jobDate = sdf.parse(job);
    } catch (java.text.ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    } catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    String sId = request.getParameter("sId").trim();
    String pId = request.getParameter("sPost").trim();// 获取的是职位
    对应的职位编号
    String sSalary = request.getParameter("sSalary").trim();
    String sIdentityId =
    request.getParameter("sIdentityId").trim();
    SqlDbUtil db = new SqlDbUtil("java:/comp/env/jdbc/permanageds");
    db.init();
    String strCmd2 = "select * from postsetting where pId ='" + pId
    + "'";
    List list2 = (List) db.query(strCmd2, null, new
    BeanListHandler(Postsetting.class));
    Postsetting ps = (Postsetting) list2.get(0);
    String dId = ps.getdId();
    String strCmd4 = "select * from postcategory where pId ='" + pId
    + "'";
    List list4 = (List) db.query(strCmd4, null, new
    BeanListHandler(Postcategory.class));
    Postcategory pc = (Postcategory) list4.get(0);
    String sPost =pc.getpName();
    String strCmd3 = "select * from department where dId ='" + dId +
    "'";
    List list3 = (List) db.query(strCmd3, null, new
    BeanListHandler(Department.class));
    Department dt = (Department) list3.get(0);
    String sDepartment = dt.getdName();// 获取到职位所隶属的部门名称
    String strCmd="update staff set sName=?, sSex=?, sBirthday=?,
    sPost=?, sDepartment=?, sSalary=?, sEntry=?, sIdentityId=? where
    sId='"+sId+"'";
    String[] params = { sName, sSex, sdf.format(birthDate),
    sPost,sDepartment, sSalary, sdf.format(jobDate), sIdentityId };
    result = db.update(strCmd, params);
    if (result == 0) {
    String message = "对不起,内容更新失败,请重新更新! <br/>";
    request.getRequestDispatcher("/staff/addstaff.jsp")
    .forward(request, response);
    } else {
    response.sendRedirect(path + "/servlet/manageStaff");
    //request.getRequestDispatcher("/servlet/manageStaff").forward(re
    quest, response);
    }

    删除功能的核心代码如下:

    String path = request.getContextPath();
    int result = 0;
    request.setCharacterEncoding("utf-8");
    String sId = request.getParameter("sId").toString();
    //String strCmd = "delete from where id='"+id+"'";
    String strCmd = "delete from staff where sId='"+sId+"'";
    SqlDbUtil dbUtil = new
    SqlDbUtil("java:/comp/env/jdbc/permanageds");
    dbUtil.init();
    result = dbUtil.update(strCmd, null);
    if(result > 0)
    response.sendRedirect(path+"/servlet/manageStaff");

    (4) 员工调动信息管理模块实现
    该模块主要是实现员工调动信息的管理,主要包括员工调动信息登记,更改和删除,
    相关核心代码与员工信息管理类似,详见源代码。 实现界面如下:

    (5) 银行账户信息模块实现
    该模块主要是实现公司银行和员工工资账户的管理,主要包括公司银行账户的创建、
    查看和修改以及员工工资账户的登记、修改和删除等功能,相关核心代码与员工信
    息管理类似, 在此不累赘, 详见源代码。 实现界面如下:

    (6) 公司信息管理模块实现
    该模块主要是实现公司相关信息的管理,主要包括公司基本信息的查看和更新、公
    司部门信息管理以及公司职位类别管理, 该模块的相关核心代码实现与员工信息管
    理类似, 在此不累赘, 详见源代码。

    (7) 系统管理模块实现
    该模块主要是实现系统管理员的管理,主要包括管理员添加、更新和删除等功能,
    相关核心代码与上面的类似,在此不累赘,详见源代码。 实现界面如下:

    四、项目代码目录结构图

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    24 Scrapy爬虫的基本使用
    22 Scrapy框架简介
    21 Scrapy框架的安装
    19 正则表达式的基本知识
    18 “中国大学排名定向爬虫”实例介绍
    17 基于bs4库的HTML内容查找方法
    16 信息标记形式及信息提取的一般方法
    python中with as语句的用法
    Firefox安装Charles配置https后无法上网解决方案(转载)
    Windows下(Win10)Charles从下载安装到证书设置和浏览器抓包测试,亲测有效!(转载)
  • 原文地址:https://www.cnblogs.com/demodashi/p/10503367.html
Copyright © 2011-2022 走看看