2021/5/23笔记文档整理

  • Post author:
  • Post category:其他




IDEA类和方法注释模板设置



设置类的注释模板

  1. File–>settings–>Editor–>File and Code Templates–>Files

    在这里插入图片描述



设置方法注释模板

IDEA还没有智能到自动为我们创建方法注释,这就是要我们手动为方法添加注释,使用Eclipse时我们生成注释的习惯是/**+Enter,这里我们也按照这种习惯来设置IDEA的方法注释

File–>Settings–>Editor–>Live Templates

选择新建模板

(1)新建组:命名为userDefine

在这里插入图片描述

(2)新建模板:命名为*

因为IDEA生成注释的默认方式是:/*+模板名+快捷键(比如若设置模板名为add快捷键用Tab,则生成方式为

/*add+Tab),如果不采用这样的生成方式IDEA中没有内容的方法将不可用,例如获取方法参数的methodParameters()、

获取方法返回值的methodReturnType()

在这里插入图片描述

(3)设置生成注释的快捷键

在这里插入图片描述

(4)设置模板:模板内容如下

注意第一行,只有一个

而不是/

在设置参数名时必须用



{参数名}




















的方式,否则第五步中读取不到你设置的参数名

/*
* @Author chengpunan
* @Description //TODO $end$
* @Date $time$ $date$
* @Param $param$
* @return $return$
**/

如果使用/

生成的模板注释将会是如下效果:所以我们要去掉最前面的/


在这里插入图片描述

(5)设置模板的应用场景

点击模板页面最下方的警告,来设置将模板应用于那些场景,一般选择EveryWhere–>Java即可

(如果曾经修改过,则显示为change而不是define)

在这里插入图片描述

(6)设置参数的获取方式

选择右侧的Edit variables按钮

PS:第五步和第六步顺序不可颠倒,否则第六步将获取不到方法

在这里插入图片描述

选择每个参数对应的获取方法(在下拉选择框中选择即可),网上有很多教程说获取param时使用脚本的方式,我试过使用脚本

的方式不仅麻烦而且只能在方法内部使用注释时才能获取到参数

在这里插入图片描述

(7)效果图

创建方法,在方法上面写:/*+模板名+Enter–>/**+Enter

在这里插入图片描述




OutputStream和InputStream的区别 + 实现java序列化

我们所说的流,都是针对内存说的,比如为什么打印到屏幕上就是System.out.println();而从屏幕等待用户输入的却是System.in呢?因为对于内存来说,把字符串打印到屏幕上是从内存流向屏幕这个显示器的,也就是输出,而从屏幕等待用户输入呢?就是等待键盘将字符输入到内存中。

所以,你根本就不用死记硬背,当你遇到IO的时候,就想两件事,第一,我的内存是中心,第二看看流的方向(矢量)!

好吧,那么往硬盘上写文件是out还是in呢?别一看到“写”文件你就说in,那是望文生义,你看,写文件的流向,是 内存———->硬盘 内存为中心,到硬盘,OK 用out 那么就是FileOutputStream、BufferedOutputStream 等等

那读文件呢?是 内存<—————硬盘 那么就是in了 , 看清楚数据的流向就OK!




Source code does not match the bytecode

使用idea时,有很方便的一点就是在对java类文件改动时不需要重新部署debug,而没有点击debug中的restart时,就会出现在Source code does not match the bytecode;

因此,类文件有所改动时,需要点击如下图

在这里插入图片描述

点击ok相当于重新部署

此时就不会出现Source code does not match the bytecode.




IDEA自动生成 Author 注释 签名

对每个文件都会生成签名

1、打开 File –> Setting–>找到 Editor

2、找到 File and Code Templates

3、找到 Includes

4、找到File Header

5、添加注释内容

在这里插入图片描述

效果:

在这里插入图片描述




命名实体识别实战(BERT)


命名实体识别实战(BERT)




json字符串转JSONObject和JSONArray以及取值

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class JsonTest {
    public static void main(String[] args) {
        String joStr = "{name:\"张三\",age:\"20\"}";
        //将json字符串转化为JSONObject
        JSONObject jsonObject = JSONObject.fromObject(joStr);
        //通过getString("")分别取出里面的信息
        String name = jsonObject.getString("name");
        String age = jsonObject.getString("age");
        //输出   张三  20
        System.out.println(name+"  "+age);
        
        String jaStr = "[{user:{name:\"张三\",age:\"20\"}},{score:{yuwen:\"80\",shuxue:\"90\"}}]";
        //将jsonArray字符串转化为JSONArray
        JSONArray jsonArray = JSONArray.fromObject(jaStr);
        //取出数组第一个元素
        JSONObject jUser = jsonArray.getJSONObject(0).getJSONObject("user");
        //取出第一个元素的信息,并且转化为JSONObject
        String name2 = jUser.getString("name");
        String age2 = jUser.getString("age");
        //输出  张三  20
        System.out.println(name2+"  "+age2);
        //取出数组第二个元素,并且转化为JSONObject
        JSONObject jScore = jsonArray.getJSONObject(1).getJSONObject("score");
        //取出第二个元素的信息
        String yuwen = jScore.getString("yuwen");
        String shuxue = jScore.getString("shuxue");
        //输出   80  90
        System.out.println(yuwen+"   "+shuxue);
    }
    
}



servlet和mysql做登录功能(熟悉servelt和mysql连接)


servlet和mysql做登录功能




Servlet连接MySQL数据库步骤

资源准备:

首先得下载对应数据库的连接包

我用的mySQl数据库所用的驱动是mysql-connector-java-8.0.18.jar

官网的下载地址是https://dev.mysql.com/downloads/connector/j/

1.加载驱动程序

Class.forName("com.mysql.cj.jdbc.Driver");

2.建立连接对象

String dburl = "jdbc:mysql://127.0.0.1:3306/数据库名?useSSL=false&serverTimezone=UTC"
Connection conn = DriverManager.getConnection(dburl,"用户名","口令");

3.创建语句对象

几种对象的创建方式不同:

Statement对象->createStatement()
PreparedStatement对象->prepareStatement()
比如创建Statement对象Statement stmt = conn.createStatement();

4.执行SQL语句并处理结果

ResultSet result = stmt.executeQuery(sql);
while(result.next()){
	out.println(result.getString(1)+"\t");
}

5.关闭建立的对象

dbconn.close();

示例

javaBean结构:

在这里插入图片描述

逻辑处理的Servlet

package com.demol;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;

@WebServlet(name = "ProductQueryServlet",urlPatterns={"/query-product"})
public class ProductQueryServlet extends HttpServlet {
    Connection dbconn = null;
    public void init() {
        String dburl  = "jdbc:mysql://127.0.0.1:3306/new_schema?useSSL=false&serverTimezone=UTC";
        String username ="用户名";
        String password = "密码";
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            dbconn = DriverManager.getConnection(dburl,username,password);
            System.out.println("数据库连接成功");
        }catch (ClassNotFoundException e1){
            System.out.println(e1+"驱动程序找不到");
        }catch(SQLException e2){
            System.out.println(e2);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //返回所有商品
        ArrayList<Product> productList = null;
        productList = new ArrayList<Product>();
        try{
            String sql = "select * from products";
            PreparedStatement pstmt = dbconn.prepareStatement(sql);
            ResultSet result = pstmt.executeQuery();
            while(result.next()){
                Product product = new Product();
                product.setId(result.getInt("id"));
                product.setPname(result.getString("pname"));
                product.setBrand(result.getString("brand"));
                product.setPrice(result.getFloat("price"));
                product.setStock(result.getInt("stock"));
                productList.add(product);
            }
            if(!productList.isEmpty()){
                request.getSession().setAttribute("productList",productList);
                response.sendRedirect("/displayAllProduct.jsp");
            }else{
                response.sendRedirect("error.jsp");
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String productid = request.getParameter("productid");
            try{
                String sql = "select * from products where id= ?";
                PreparedStatement pstmt = dbconn.prepareStatement(sql);
                pstmt.setString(1,productid);
                ResultSet result = pstmt.executeQuery();
                if(result.next()){
                    Product product = new Product();
                    product.setId(result.getInt("id"));
                    product.setPname(result.getString("pname"));
                    product.setBrand(result.getString("brand"));
                    product.setPrice(result.getFloat("price"));
                    product.setStock(result.getInt("stock"));
                    request.getSession().setAttribute("product",product);
                    response.sendRedirect("displayProduct.jsp");
                }else{
                    response.sendRedirect("error.jsp");
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
    }
    public void destroy(){
        try{
            dbconn.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}





C3P0基本使用教程

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。

  1. 导入jar包:c3p0-0.9.5.2.jar C3P0核心

    mchange-commons-java-0.2.12.jar C3P0依赖

    mysql-connector-java-5.1.37-bin.jar 数据库连接驱动(这里使用的是MySQL)

    下载连接:

    https://pan.baidu.com/s/1rsP9dA8wB3JvOctUs5BVsg
  2. 将jar包复制到libs文件夹,将jar包添加到库文件中(右击libs–>Add As Library–>ok)
  3. 定义配置文件:


    名称:c3p0.properties 或者 c3p0-config.xml



    位置:src目录下
  4. c3p0-config.xml内容
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
     <!--  连接参数 -->
    <!--  驱动名称  -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <!--  数据库URL  -->
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/dbname</property>
    <!--  用户名  -->
    <property name="user">root</property>
    <!--  密码  -->
    <property name="password">root</property>
    
    <!-- 连接池参数 -->
    <!--  初始连接数量  -->
    <property name="initialPoolSize">5</property>
    <!--  最大连接数  -->
    <property name="maxPoolSize">10</property>
    <!--  超时时间  -->
    <property name="checkoutTimeout">3000</property>
  </default-config>
</c3p0-config>
  1. 使用C3P0
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class C3P0Demo1 {
    public static void main(String[] args) {
        String sql = "select * from student where id = ?";
        Scanner sc = new Scanner(System.in);
        int id = sc.nextInt();
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //创建数据库连接池对象
            DataSource ds = new ComboPooledDataSource();
            //获取数据库连接对象
            conn = ds.getConnection();
            //获取statement,使用prepareStatement,防止sql注入
            pstmt = conn.prepareStatement(sql);
            //注入sql参数(sql中?将被替换)
            pstmt.setInt(1,id);
            //执行sql,返回数据集
            ResultSet rs = pstmt.executeQuery();
            //数据处理
            System.out.println(rs);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //释放stmt
            if(pstmt != null){
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //conn归还连接池
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}




Druid数据库连接池

数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出来的.数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。

如何使用Druid连接池:



第一步:首先下载Druid的jar包,导入环境;当然也可以用maven导入



第二步:编写配置文件:

Druid.properties配置文件

driverClassName = com.mysql.cj.jdbc.Driver
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///student?serverTimezone=GMT&useSSL=false
username=root
password=yanzhiguo140710
#初始化连接数量#
initialSize = 5
#最大连接数量
maxACtive = 10
#等待时间 3秒
maxWait = 3000
 

在这里插入图片描述



第三步:导入配置文件,使用Druid连接池

具体实现方法如下:

package Druid;
 
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
 
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
public class DruidDemo {
    public static void main(String[] args) {
        //1.导入jar包
        //2.定义配置文件
        //3.加载配置文件
        Properties pro = new Properties();
        InputStream resourceAsStream = DruidDemo.class.getClassLoader().getResourceAsStream("Druid.properties");
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            pro.load(resourceAsStream);
            DataSource ds = DruidDataSourceFactory.createDataSource(pro);
            connection = ds.getConnection();
            String sql = "Select * from goods";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
               Integer id = resultSet.getInt("id");
               String name = resultSet.getString("name");
               String value = resultSet.getString("value");
                System.out.println(id+" "+name+" "+value);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (preparedStatement!=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
 
        }
 
    }
 
}

但是总不能每一次使用都这样使用吧,这就需要写一个DruidUtil的工具类,这样才能能方便快捷的写代码。




DruidUtil类:

package Util;
 
import com.alibaba.druid.pool.DruidDataSourceFactory;
 
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
 
public class DruidUtil {
 
    private static DataSource ds;
 
    static {
        //加载配置文件和建立连接池
        try {
            Properties pro = new Properties();
            InputStream resourceAsStream = DruidUtil.class.getClassLoader().getResourceAsStream("Druid.properties");
            pro.load(resourceAsStream);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取数据库连接池
     * @return
     */
    public static DataSource getDataSource(){
        return ds;
    }
 
 
    /**
     * 获取连接池中的一个连接
     * @return
     * @throws SQLException
     */
    public Connection getconnection() throws SQLException {
        return ds.getConnection();
 
    }
 
 
    /**
     * 关闭数据库的资源  三个对象都存在时
     * @param conn
     * @param res
     * @param pstmt
     */
    public static void close(Connection conn, ResultSet res, PreparedStatement pstmt){
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (res!=null){
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt!=null){
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
 
    /**
     * 关闭数据库的连接(只存在Connection和PreparedStatement对象时)
     * @param conn
     * @param pstmt
     */
    public void close(Connection conn,PreparedStatement pstmt){
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt!=null){
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
 
}

我们来测试一下这个工具类写的正确与否:



DruidUtil类使用范例

package Druid;
 
import Util.DruidUtil;
 
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
public class DruidDemo2 {
    public static void main(String[] args) throws SQLException {
        DataSource ds = DruidUtil.getDataSource();
        Connection connection = ds.getConnection();
        String sql = "select * from goods";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()){
            Integer id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String value = resultSet.getString("value");
            System.out.println(id+" "+name+" "+value);
        }
        DruidUtil.close(connection,resultSet,preparedStatement);
    }
}
**或者使用maven的方式**



添加druid的依赖、数据库驱动

		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.8</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>



纯代码方式

//数据源配置
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://127.0.0.1/db_student?serverTimezone=UTC");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); //这个可以缺省的,会根据url自动识别
        dataSource.setUsername("root");
        dataSource.setPassword("abcd");
        
        //下面都是可选的配置
        dataSource.setInitialSize(10);  //初始连接数,默认0
        dataSource.setMaxActive(30);  //最大连接数,默认8
        dataSource.setMinIdle(10);  //最小闲置数
        dataSource.setMaxWait(2000);  //获取连接的最大等待时间,单位毫秒
        dataSource.setPoolPreparedStatements(true); //缓存PreparedStatement,默认false
        dataSource.setMaxOpenPreparedStatements(20); //缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句代码

        //获取连接
        Connection connection = dataSource.getConnection();

        //Statement接口
        Statement statement = connection.createStatement();
        String sql1 = "insert into tb_student (name,age) values ('chy',20)";
        statement.executeUpdate(sql1);

        //PreparedStatement接口
        String sql2 = "insert into tb_student (name,age) values ('chy',21)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql2);
        preparedStatement.execute();

        //关闭连接
        connection.close();



配置文件方式

1、在sources下新建druid.properties

url=jdbc:mysql://127.0.0.1/db_student?serverTimezone=UTC
#这个可以缺省的,会根据url自动识别
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=abcd

##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20

2、使用

public class Test {
    
    public static void main(String[] args) throws Exception {
        //数据源配置
        Properties properties=new Properties();
        //通过当前类的class对象获取资源文件
        InputStream is = Test.class.getResourceAsStream("/druid.properties"); 
        properties.load(is);
        //返回的是DataSource,不是DruidDataSource
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

        //获取连接
        Connection connection = dataSource.getConnection();

        //Statement接口
        Statement statement = connection.createStatement();
        String sql1 = "insert into tb_student (name,age) values ('chy',20)";
        statement.executeUpdate(sql1);

        //PreparedStatement接口
        String sql2 = "insert into tb_student (name,age) values ('chy',22)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql2);
        preparedStatement.execute();

        //关闭连接
        connection.close();
    }
    
}



mysql中表类型varchar要设置长度 不然报 1064错误,或者使用char解决




微信公众号开发之时间转换

在微信公众号开发中,与微信服务器交互的几乎所有接口中的时间参数都是以整型为类型的,要正确的展示时间那必须进行转换。关于时间整型的描述:最初计算机操作系统是32位,而时间也是用32位表示。32位能表示的最大值是2147483647。另外1年365天的总秒数是31536000,2147483647/31536000 = 68.1,也就是说32位能表示的最长时间是68年,而实际上到2038年01月19日03时14分07秒,便会到达最大时间,过了这个时间点,所有32位操作系统时间便会变为10000000 00000000 00000000 00000000,也就是1901年12月13日20时45分52秒,这样便会出现时间回归的现象,很多软件便会运行异常了。到这里,我想问题的答案已经出来了:因为用32位来表示时间的最大间隔是68年,而最早出现的UNIX操作系统考虑到计算机产生的年代和应用的时限综合取了1970年1月1日作为UNIX TIME的纪元时间(开始时间),至于时间回归的现象相信随着64为操作系统的产生逐渐得到解决,因为用64位操作系统可以表示到292,277,026,596年12月4日15时30分08秒,相信我们的N代子孙,哪怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后了。

也就是说:时间整型其实就是 1970年1月1日以来的秒数,那么原理弄清楚了,这就简单了

	public static String paserTime(int time){
	      System.setProperty("user.timezone", "Asia/Shanghai");
	      TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
	      TimeZone.setDefault(tz);
	      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	      String times = format.format(new Date(time * 1000L));
	      System.out.print("日期格式---->" + times);
	      return times;
	}




javax.imageio.IIOException: Can’t create output stream解决方法





生成带二维码的海报图—批量生成多个





java合成海报的工具类(二维码、头像、海报)




shortUrl生成随机码

    /**
     * 短网址生成方法
     * 这个方法会,生成四个短字符串,每一个字符串的长度为6
     * 这个方法是从网上搜索的一个方法,但不知道出自何处了,稍微将key换了一下
     * @param url
     * @return
     */
public static String[] shortUrl(String url) {

        // 可以自定义生成 MD5 加密字符传前的混合 KEY
        String key = UUID.randomUUID().toString();
        
        //混淆key,加上当前时间,并且取一个随机字符串
        key = System.currentTimeMillis() + key;
        // 要使用生成 URL 的字符

        String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h",

                "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",

                "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",

                "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",

                "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",

                "U", "V", "W", "X", "Y", "Z"
        };

        // 对传入网址进行 MD5 加密
        String sMD5EncryptResult = EncryptionUtils.md5(key + url);

        String hex = sMD5EncryptResult;

        String[] resUrl = new String[4];

        for (int i = 0; i < 4; i++) {

            // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算

            String sTempSubString = hex.substring(i * 8, i * 8 + 8);

            // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用
            // long ,则会越界

            long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);

            String outChars = "";

            for (int j = 0; j < 6; j++) {

                // 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引

                long index = 0x0000003D & lHexLong;

                // 把取得的字符相加

                outChars += chars[(int) index];

                // 每次循环按位右移 5 位

                lHexLong = lHexLong >> 5;

            }

            // 把字符串存入对应索引的输出数组

            resUrl[i] = outChars;

        }
        
        return resUrl;
    }

    /**
     * 获取我想要的字符串,将生成的两个相加,得到我想要的12位字符
     * @param url
     * @return
     */
    public static String getShortUrl(String url){
        String[] aResult = shortUrl(url);
        
        return aResult[0] + aResult[1];
    }
    
    //测试方法
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        for(int i = 0;i<1000;i++){
            sb.append("ab");//长度为2000的一个字符串
        }
        
        String[] strings = shortUrl(sb.toString());
        for(int i = 0;i<strings.length;i++){
            System.out.println(strings[i]);
        }
        
        //验证生成的是否是唯一的
        List<String> list = new ArrayList<>();
        //生成1000万个短字符,已经足够使用
        for (int i = 0; i<10000000; i++){
            list.add(getShortUrl(sb.toString()));
        }
        
        //经测试生成1000万个短链接没有重复的
        //这里的判断重复的方法,是使用的SF上面一位网友的方法,我觉得比较优雅,只使用一次循环,而且也能判断,所以就使用了他的方法
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        for (String string : list) {
            if (hashMap.get(string) != null) {
                Integer value = hashMap.get(string);
                hashMap.put(string, value+1);
                System.out.println("the element:"+string+" is repeat");
            } else {
                hashMap.put(string, 1);
            }
        }
    }
    
    最后输出:
    BFVRfa
    muI7Nn
    3Ibeau
    aQRBzy
    
    输出表明确实没有重复的,答到需要的结果




JAVA字符串压缩解压缩方法

package com.util;   
  
import java.io.ByteArrayInputStream;   
import java.io.ByteArrayOutputStream;   
import java.io.IOException;   
import java.util.zip.GZIPInputStream;   
import java.util.zip.GZIPOutputStream;   
  
// 将一个字符串按照zip方式压缩和解压缩   
public class ZipUtil {   
  
  // 压缩   
  public static String compress(String str) throws IOException {   
    if (str == null || str.length() == 0) {   
      return str;   
    }   
    ByteArrayOutputStream out = new ByteArrayOutputStream();   
    GZIPOutputStream gzip = new GZIPOutputStream(out);   
    gzip.write(str.getBytes());   
    gzip.close();   
    return out.toString(&quot;ISO-8859-1&quot;);   
  }   
  
  // 解压缩   
  public static String uncompress(String str) throws IOException {   
    if (str == null || str.length() == 0) {   
      return str;   
    }   
    ByteArrayOutputStream out = new ByteArrayOutputStream();   
    ByteArrayInputStream in = new ByteArrayInputStream(str   
        .getBytes(&quot;ISO-8859-1&quot;));   
    GZIPInputStream gunzip = new GZIPInputStream(in);   
    byte[] buffer = new byte[256];   
    int n;   
    while ((n = gunzip.read(buffer)) &gt;= 0) {   
      out.write(buffer, 0, n);   
    }   
    // toString()使用平台默认编码,也可以显式的指定如toString(&quot;GBK&quot;)  
    return out.toString();   
  }   
  
  // 测试方法   
  public static void main(String[] args) throws IOException {   
         
      //测试字符串   
      String str="%5B%7B%22lastUpdateTime%22%3A%222011-10-28+9%3A39%3A41%22%2C%22smsList%22%3A%5B%7B%22liveState%22%3A%221";   
         
      System.out.println("原长度:"+str.length());     
         
      System.out.println("压缩后:"+ZipUtil.compress(str).length());     
         
    System.out.println("解压缩:"+ZipUtil.uncompress(ZipUtil.compress(str)));   
  }   
  
} 




加密解密五种算法的实现

①单字母替换加密方法——恺撒密码

加密方法是把英文字母按字母表的顺序编号作为明文,将密钥定为m,加密算法为将明文加上密钥m,得到密码表,通过相反的过程由密文得到明文。

②单字母替换加密方法——字母倒排序

在加密、解密的过程中明文和密文按照字母表的顺序倒排对应,即A对应Z,B对应Y。

③单字母替换加密方法——单表置换密码

由密钥Key构造字符置换表,完成加密和解密过程。

④多字母替换加密方法——维吉利亚密码

假设明文m=m1 m2 m3 … mn;密钥k=k1k2 k3 … kn,对应密文c=c1 c2 c3 … cn,密文为:ci=(mi+ki )mod 26 ,26个字母的序号依次为0~25,ci , mi ,ki是分别是密文明文密钥中第i个字母的序号。




java中的 string和char数组的相互转换

String转char数组
 
 
 
这个要看你的具体需求了.如果是有分隔符的那种例如"a,b,c";就直接分割就行了.
 
String string = "a,b,c";
String [] stringArr= string.split(",");  //注意分隔符是需要转译滴...
 
如果是"abc"这种字符串,就直接
String string = "abc" ;
char [] stringArr = string.toCharArray(); //注意返回值是char数组
 
如果要返回byte数组就直接使用getBytes方法就ok了~~
String string = "abc" ;
byte [] stringArr = string.getBytes();



jbbc开启事务

try{
     con.setAutoCommit(false);//开启事务   这里要写在sql.excute执行前
     ......
     con.commit();//try的最后提交事务      
} catch() {
    con.rollback();//回滚事务
}



js前端获取页面传递的参数

UrlParm = function () { // url参数
    var data, index;
    (function init() {
        data = [];
        index = {};
        var u = window.location.search.substr(1);
        if (u != '') {
            var parms = decodeURIComponent(u).split('&');
            for (var i = 0, len = parms.length; i < len; i++) {
                if (parms[i] != '') {
                    var p = parms[i].split("=");
                    if (p.length == 1 || (p.length == 2 && p[1] == '')) {
                        data.push(['']);
                        index[p[0]] = data.length - 1;
                    } else if (typeof (p[0]) == 'undefined' || p[0] == '') {
                        data[0] = [p[1]];
                    } else if (typeof (index[p[0]]) == 'undefined') { // c=aaa
                        data.push([p[1]]);
                        index[p[0]] = data.length - 1;
                    } else {// c=aaa
                        data[index[p[0]]].push(p[1]);
                    }
                }
            }
        }
    })();
    return {
        // 获得参数,类似request.getParameter()
        parm: function (o) { // o: 参数名或者参数次序
            try {
                return (typeof (o) == 'number' ? data[o][0] : data[index[o]][0]);
            } catch (e) {
            }
        },
        //获得参数组, 类似request.getParameterValues()
        parmValues: function (o) { //  o: 参数名或者参数次序
            try {
                return (typeof (o) == 'number' ? data[o] : data[index[o]]);
            } catch (e) { }
        },
        //是否含有parmName参数
        hasParm: function (parmName) {
            return typeof (parmName) == 'string' ? typeof (index[parmName]) != 'undefined' : false;
        },
        // 获得参数Map ,类似request.getParameterMap()
        parmMap: function () {
            var map = {};
            try {
                for (var p in index) { map[p] = data[index[p]]; }
            } catch (e) { }
            return map;
        }
    }
} ();

调用

 var  idx = UrlParm.parm('IDX');



页面通过response.sendRedirect()跳转后的取值问题

重定向是重新发起一个request,之前你设定attribute的request的生命周期已经结束

试试forward

sendRedirect()跳转后是不属于同一请求,request里面的属性是取不到的,用session.setAttribute();

response.sendRedirect(“/index2.jsp?params=123”);URL后面带参数

sendRedirect是重新开启一个request,还是用forward吧

如果是在同一个web project,还是用dispatcher比较好。




JavaScript向页面输出内容的四种方法

javascript可以通过不同的方式来输出数据

1.使用window.alert()输出警告框

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>弹出框</title>
</head>
<script>
alert("通过弹出框输出内容");
</script>
<body>
</body>
</html>

2.使用console.log()写入到浏览器的控制台

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>通过console向控制台输出内容</title>
</head>
<script>
console.log("通过console向控制台输出了内容")
</script>
<body>
</body>
</html>

3.使用innerHTML写入到HTML元素

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>通过innerHTML方法向页面元素中输出内容</title>
</head>
<script>
function changeContent() {
document.getElementById("demo").innerHTML = "通过innerHTML方法向页面输出了内容";
}
</script>
<body>
<h1 id="demo">我是一个标题</h1>
<button type="button" onclick="changeContent()">更改内容</button>
</body>
</html>

4.使用document.write()方法将内容写到html文档中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>write输出内容到页面中</title>
</head>
<script>
document.write("hello");
document.write("<h1>通过document.write输出内容</h1>");
</script>
<body>
</body>
</html>





IDEA Tomcat控制台中文乱码

6.通过设置修改VmOption(解决)

这个不同于方法2,这个是通过程序提供的方法修改参数,最终测试有效

Help->Edit Custom VM Options…,添加一行-Dfile.encoding=UTF-8

在这里插入图片描述





Idea中创建 Servlet过程

在服务器端,要转变请求的字符串编码,用request.setCharacterEncoding(“UTF-8”);这个方法要放在jsp代码的request.getParameter()方法前面。如





java教程 关于idea对javaweb项目的编译打包配置详细说明 和 deployment source ‘xxx:war exploded’ is not valid全面分析




如何解决在IDEA中Debug时出现了”Source code does not match the bytecode”警告

今天,在IDEA中进行debug代码测试时,出现了”Source code does not match the bytecode”字样,翻译下来其实是“源代码与字节码不匹配”。

经过百度查询,原因是你的代码更改添加了,但是并未重新编译一下,所以添加的代码idea就探测不到,只需要重新debug restart一下/Build Project,即可解决。




关注公众号自动回复两条消息


调用客服接口,回复文字信息


$content = ‘Hello Word’;


KaTeX parse error: Expected ‘}’, got ‘EOF’ at end of input: … “touser” : “‘.

openid.’”,

“msgtype” : “text”,

“text” : {


“content” : “’.$content.’”

}

}’;




u

r

l

=

h

t

t

p

s

:

/

/

a

p

i

.

w

e

i

x

i

n

.

q

q

.

c

o

m

/

c

g

i

b

i

n

/

m

e

s

s

a

g

e

/

c

u

s

t

o

m

/

s

e

n

d

?

a

c

c

e

s

s

t

o

k

e

n

=

.

url = “https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=”.






u


r


l




=











h


t


t


p


s




:








/


/


a


p


i


.


w


e


i


x


i


n


.


q


q


.


c


o


m


/


c


g


i













b


i


n


/


m


e


s


s


a


g


e


/


c


u


s


t


o


m


/


s


e


n


d


?


a


c


c


e


s



s










t


















o


k


e


n




=











.





access_token;




r

e

s

u

l

t

=

h

t

t

p

s

r

e

q

u

e

s

t

(

result = https_request(






r


e


s


u


l


t




=








h


t


t


p



s










r


















e


q


u


e


s


t


(





url ,



d

a

t

a

)

;

v

a

r

d

u

m

p

(

data); var_dump(






d


a


t


a


)


;




v


a



r










d


















u


m


p


(





result);


和默认设置的回复消息



这样就可以实现回复两条消息了




JSONObject.fromObject(obj) 报错

自动导包一般会导入这个,

import com.alibaba.fastjson.JSONObject;

其实需要的是这个:

import net.sf.json.JSONObject;

二、解决办法

1、方法一:下载jar包

不推荐,基本网上的jar包资源都需要付费

2、方法二:添加 maven pom.xml 依赖

在maven repository里搜索

在这里插入图片描述

三、如果需要转化对象较为复杂,最好使用Gson

public  @ResponseBody AjaxResponse saveArticle (@RequestBody String   article){
 
    log.info("saveArticle : {}",article);
 
   Gson gson = new Gson();
   Article article1 = gson.fromJson(article, Article.class);
 
    return AjaxResponse.success(article);
}



或者导入fastjson的maven包

 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>



接口网站


https://www.zhihu.com/question/38482653/answer/1247269190




微信助力活动表结构设计

在这里插入图片描述




java之JDBC多条语句执行

  pstat = con.prepareStatement("update userr set money=money-? where name=?");
            pstat.setInt(1, 100);
            pstat.setString(2, "李四");
            pstat.executeUpdate();
            pstat = con.prepareStatement("update userr set money=money+? where name=?");
            pstat.setInt(1, 200);
            pstat.setString(2, "张三");
            pstat.executeUpdate();            
            pstat = con.prepareStatement("update temp set count=count+? where name=?");
            pstat.setInt(1, 1);
            pstat.setString(2, "张三");
            pstat.executeUpdate();
            con.commit();
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Arrays;
 
import org.junit.Test;
 
import cn.itcast.e_tool.JDBCUtils;
public class Demo {
	@Test
	//1 使用Statement对象批量执行sql
	public void fun1() throws Exception{
		
		//1 获得连接
		Connection conn = JDBCUtils.getConnection();
		//2 获得Statement
		Statement st =	conn.createStatement();
		//3 添加多条sql语句到st中
	
	st.addBatch("create table t_stu ( id int primary key auto_increment , name varchar(20) )");
	st.addBatch("insert into t_stu values(null,'tom')");
	st.addBatch("insert into t_stu values(null,'jerry')");
	st.addBatch("insert into t_stu values(null,'jack')");
	st.addBatch("insert into t_stu values(null,'rose')");
		//4 执行sql
	int[]  results = st.executeBatch();
	System.out.println(Arrays.toString(results));
		//5关闭资源
		JDBCUtils.close(conn, st, null);
		}
	@Test
	//2 使用PrepareStatement对象批量执行sql
	public void fun2() throws Exception{
		
		//1 获得连接
		Connection conn = JDBCUtils.getConnection();
		//2 书写sql语句
		String sql = "insert into t_stu values(null,?)";
		//3 创建PrepareStatement
		PreparedStatement ps = conn.prepareStatement(sql);
		//4 循环.添加参数
		for(int i=0;i<100;i++){
			ps.setString(1, "用户"+i);
			ps.addBatch();
		}
		//5 批量执行
		int[]  results =ps.executeBatch();
		System.out.println(Arrays.toString(results));
		//5关闭资源
		JDBCUtils.close(conn, ps, null);
		}
}



版权声明:本文为dianyanxia原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。