首页
关于
Search
1
sql的注入原因和解决办法
138 阅读
2
SpringBoot整合腾讯云存储COS及基本使用,增删改查......
128 阅读
3
深究contains方法
100 阅读
4
多线程概述
74 阅读
5
学习的第一个注解@WebServlet - JavaWeb
73 阅读
默认分类
Java
C/C++
Mysql
JavaWeb
SpringBoot
算法
前端
Linux
Search
标签搜索
Spring
HTTP
Java
JavaWeb
IOC
mybatis
腾讯云
COS
云存储
CDN
redis
分布式
id
全局唯一id
Typecho
累计撰写
26
篇文章
累计收到
2
条评论
首页
栏目
默认分类
Java
C/C++
Mysql
JavaWeb
SpringBoot
算法
前端
Linux
页面
关于
搜索到
26
篇与
achong
的结果
2022-10-27
SpringBoot集成腾讯云短信JDK,实现短信发送!!!
腾讯云原文地址,原文更详细,我下面的代码略有修改,只保留了与发送短信相关的代码。https://cloud.tencent.com/document/product/382/43194#.E5.8F.91.E9.80.81.E7.9F.AD.E4.BF.A1腾讯云短信控制台: https://console.cloud.tencent.com/smsv2 短信签名、模板ID、短信应用ID项目pom文件引入腾讯云短信接口的sdk <dependency> <groupId>com.tencentcloudapi</groupId> <artifactId>tencentcloud-sdk-java</artifactId> <!-- go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version. --> <!-- 请到https://search.maven.org/search?q=tencentcloud-sdk-java查询所有版本,最新版本如下 --> <version>3.1.612</version> </dependency>配置tencentCloud.properties文件在resources目录下,用于保存腾讯云的用户API密钥tencent.cloud.secretId=AKc6Si**********BtQmvtiMo5me5S tencent.cloud.secretKey=NYWIuK**********spdIE1fPW tencent.cloud.sdkAppId=短信应用ID tencent.cloud.signName=短信签名内容 tencent.cloud.templateId=模板 ID创建一个实体类,用于读取密钥与短信相关配置@Component @Data @PropertySource(value = "classpath:tencentCloud.properties", encoding = "UTF-8") @ConfigurationProperties(prefix = "tencent.cloud") public class TencentCloudProperties { // 腾讯云账户密钥对 private String secretId; private String secretKey; // 短信应用ID private String sdkAppId ; // 短信签名内容 private String signName ; // 模板 ID private String templateId ; }将发送短信相关代码封装成一个工具类 经过封装后,调用该方法时只需传入手机号码和验证码,事后会返回SDK的一个短信发送结果封装类SendSmsResponse。package com.achong.utils; import com.achong.bean.TencentCloudProperties; import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.sms.v20210111.SmsClient; // 注意 SendSmsRequest 和 SendSmsResponse 是在同一个包下 import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest; import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class SMSUtils { @Autowired private TencentCloudProperties tencentCloudProperties; /** * 发送短信 post请求 */ public SendSmsResponse sendSMS(String phone, String verCode){ System.out.println("=========================================="); System.out.println(tencentCloudProperties.toString()); System.out.println("=========================================="); // 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。 Credential cred = new Credential(tencentCloudProperties.getSecretId(), tencentCloudProperties.getSecretKey()); /* 实例化要请求产品的client对象 * 第一个参数是认证对象 * 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */ SmsClient client = new SmsClient(cred, "ap-guangzhou"); // 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数 SendSmsRequest request = new SendSmsRequest(); /** * 以下是填充请求信息 */ /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */ // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看 request.setSmsSdkAppId(tencentCloudProperties.getSdkAppId()); /* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */ // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看 request.setSignName(tencentCloudProperties.getSignName()); /* 模板 ID: 必须填写已审核通过的模板 ID */ // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看 request.setTemplateId(tencentCloudProperties.getTemplateId()); /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 */ String[] templateParamSet = {verCode}; request.setTemplateParamSet(templateParamSet); /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号] * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */ String[] phoneNumberSet = {"86" + phone}; request.setPhoneNumberSet(phoneNumberSet); /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的 * 返回的 response 是一个 SendSmsResponse 类的实例,与请求对象对应 */ SendSmsResponse response = null; try { response = client.SendSms(request); } catch (TencentCloudSDKException e) { e.printStackTrace(); } // 输出json格式的字符串回包 System.out.println(SendSmsResponse.toJsonString(response)); //方法将返回 短信发送结果 的对象 return response; } } 创建Controller调用上面封装的工具类发送短信进行测试。package com.achong.controller; import com.achong.utils.SMSUtils; import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SendSMSController { @Autowired private SMSUtils smsUtils; @RequestMapping("/sendSms") public void sendSms(String phone){ if (phone == null || phone == "" || phone.length() != 11) { System.out.println("手机号错误"); return; } // 本地生成四位数验证码,短信位数可调整 10000 的位数 String code = (int)((Math.random() * 9 + 1) * 10000) + ""; // 调用工具类发送短信,参数分别是 手机号码 和 验证码。 SendSmsResponse response = smsUtils.sendSMS(phone, code); // 格式化打印输出短信发送结果 System.out.println(SendSmsResponse.toJsonString(response)); // 拿到 短信发送结果 里的 Code 字段,该字段表示 短信是否发送成功 String status = response.getSendStatusSet()[0].getCode(); if ("Ok".equals(status)){ System.out.println("发送成功,状态码:"+status); }else { System.out.println("发送失败,状态码:"+status); } } } 浏览器测试访问地址:http://localhost:8080/sendSms?phone=17310101010发送成功后,页面会返回短信发送结果,格式为 JSON字符串,其中Code字段为短信发送结果,成功则该字段为Ok,否则是其他错误信息。该字段可以作为判断短信发送是否成功的依据。 { "SendStatusSet": [{ "SerialNo": "3369:76164835516668596094641947", 发送流水号。 "PhoneNumber": "+8617310101010", 手机号码,E.164标准,+[国家或地区码][手机号] ,示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号。 "Fee": 1, 计费条数 "SessionContext": "", 用户 session 内容。 "Code": "Ok", 短信请求错误码 "Message": "send success", 短信请求错误码描述。 "IsoCode": "CN" 国家码或地区码,例如 CN、US 等,对于未识别出国家码或者地区码,默认返回 DEF }], "RequestId": "b9a8468f-12bb-4985-bda7-5592d56f98bd" }
2022年10月27日
64 阅读
0 评论
2 点赞
2022-08-12
bs_typeadhead - 关键字自动补全插件
bs_typeadhead - 文本框关键字自动补全插件此插件基于bootstrap首先引入三大部分的依赖jquery、bootstrap、bs_typeadhead<%-- jquery--%> <script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script> <!-- bootstrap --> <link rel="stylesheet" href="jquery/bootstrap_3.3.0/css/bootstrap.min.css"> <script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script> <%-- bs_typeadhead--%> <script type="text/javascript" src="jquery/bs_typeahead/bootstrap3-typeahead.min.js"></script>页面添加一个div容器<input type="text" id="customerName">在入口函数,对容器注册bs_typeadhead 函数部分说明:typeahead( ) 函数的source属性就是自动补全的数据的来源,来源分为静态数据和动态数据。静态数据:可以是数组 [ ]。动态数据:source是一个函数,里面是ajax请求,请求的结果必须是可遍历的json对象<script type="text/javascript"> $(function (){ $("#customerName").typeahead({ //数据的来源-静态 // source:['京东商城','阿里巴巴','百度科技公司','字节跳动','动力节点'] //数据的来源-动态 source:function(jquery,process){ //参数列表里的process是一个函数,作用是把ajax返回的data赋值给属性source。 //用户在容器中获取的关键字 //发送请求 $.ajax({ url:'workbench/transaction/queryCustomerNameByName.do?customerName'+jquery, type:'post', dataType:'json', success:function (data){ process(data); //参数列表里的process是一个函数,作用是把ajax返回的data赋值给属性source。 } }); } }); });ajax请求部分对应的后端代码 @RequestMapping("/workbench/transaction/queryCustomerNameByName.do") @ResponseBody public List<String> queryCustomerNameByName(String customerName){ List<String> customerNameList = customerService.queryCustomerNameByName(); return customerNameList; }typeahead( ) 函数的其他属性source: 规定包含查询时要显示的值的数据源。值的类型是 array,默认值是 [ ]。items: 规定查询时要显示的条目的最大值。数据类型是 number,默认值是 8。matcher: 决定查询是否匹配条目。带有一个单一的参数,即要测试查询的条目。当前查询通过 this.query 访问。返回一个布尔值 true,表示查询匹配。数据类型是 function。默认情况下是大小写不敏感的。sorter: 用于自动分类结果。带有一个单一的参数,即具有 typeahead 实例范围的条目。当前查询通过 this.query 访问。数据类型是 function。默认值是精确匹配的,其他的值还可以是大小写敏感、大小写不敏感。highlighter: 用于自动高亮突出显示结果。带有一个单一的参数,即具有 typeahead 实例范围的条目。数据类型是 function。默认情况下是高亮突出显示所有默认的匹配项。
2022年08月12日
49 阅读
0 评论
0 点赞
2022-08-01
日历插件datatimepicker的使用 - JSP
DateTimePicker图形化日历时间日期选择器DateTimePicker是基于JQuery的时间日期选择插件。只需要2行代码,即可轻松实现网页图形化日期时间选择器。 datatimepicker软件包下载地址:https://www.datetimepicker.cn/download/有一个编辑框<body> <input id="myDate" type="text" readonly> </body>然后按顺序引入相关css和jsjquery依赖bootstrap框架dataTimePicker插件<%-- jquery--%> <script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script> <%-- bootstrapk框架--%> <link rel="stylesheet" href="jquery/bootstrap_3.3.0/css/bootstrap.min.css"> <script type="text/javascript" href="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script> <%-- bootstrap datetimepicker插件--%> <link rel="stylesheet" href="jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css"> <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script> <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js"></script>在页面加载完成后注册插件<script type="text/javascript"> $(function (){ //当容器加载完成,对容器调用工具函数 $("#myDate").datetimepicker({ language:'zh-CN', //语言 format:'yyyy-mm-dd', //日期格式 minView:'month', //最小精度 autoclose:'true', //默认值false,当选择一个日期之后是否立即关闭此日期时间选择器。 initData:new Date(), //默认时间 todayBtn:'ture', //是否显示选择当前时间按钮 clearBtn:'true' //是否显示清空按钮 }); })完整代码<%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/"; %> <html> <head> <base href="<%=basePath%>"> <meta charset="UTF-8"> <%-- jquery--%> <script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script> <%-- bootstrapk框架--%> <link rel="stylesheet" href="jquery/bootstrap_3.3.0/css/bootstrap.min.css"> <script type="text/javascript" href="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script> <%-- bootstrap datetimepicker插件--%> <link rel="stylesheet" href="jquery/bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.min.css"> <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.js"></script> <script type="text/javascript" src="jquery/bootstrap-datetimepicker-master/locale/bootstrap-datetimepicker.zh-CN.js"></script> <title>演示bs_datetimepicker插件</title> <script type="text/javascript"> $(function (){ //当容器加载完成,对容器调用工具函数 $("#myDate").datetimepicker({ language:'zh-CN', //语言 format:'yyyy-mm-dd', //日期格式 minView:'month', //最小精度 autoclose:'true', //默认值false,当选择一个日期之后是否立即关闭此日期时间选择器。 initData:new Date(), //默认时间 todayBtn:'ture', //是否显示选择当前时间按钮 clearBtn:'true' //是否显示清空按钮 }); }) </script> </head> <body> <input type="text" id="myDate" readonly> </body> </html>
2022年08月01日
63 阅读
0 评论
0 点赞
2022-07-09
手动注入JdbcTemplate - SpringBoot
在Spring的某些无法自动注入的情况下,可以选择手动注入。数据源:就是配置数据库的驱动、连接地址、账号、密码//配置数据源 DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/userdb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); //new出JdbcTemplate,并将数据源放入其构造方法 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);例子将注入过程放到类的构造方法比较合理。@SpringBootTest public class mysqlTest { private JdbcTemplate jdbcTemplate; public mysqlTest(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/userdb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"); dataSource.setUsername("root"); dataSource.setPassword("123456"); this.jdbcTemplate = new JdbcTemplate(dataSource); } @Test public void contextLoads(){ Long count = jdbcTemplate.queryForObject("select count(*) from userinfo", Long.class); System.out.println("userinfo数据表记录总数为:" + count); } }
2022年07月09日
34 阅读
0 评论
0 点赞
2022-05-16
记一个二分查找
被查找的数组必须是有序。 public class HelloWorld{ public static void main(String[] args){ //被查找数组,必须是有序 int[] arr = {1,3,5,7,9,11,13,14}; //被查找目标 int target = 14; //定义左、右、中间下标 int start = 0; int end = arr.length - 1; int mid; //循环结束条件:左下标 小于等于 右下标。 while(start <= end){ mid = (start + end) / 2; //初始化中间下标 //如果中间元素和目标相同,直接return。否则继续判断 if(target == arr[mid]) { System.out.println("ok, target = " + mid); return; } else if(target > arr[mid]) { //如果目标大于中间值,说明目标在中间值的右边。 //把左下标改到中间下标的后一位。 start = mid+1; } else { //如果不符合上面,目标就一定小于中间值。 //把右下标改为中间下标的前一位 end = mid-1; } } //若程序执行到这里,说明没找到。 System.out.println("NO"); } }
2022年05月16日
52 阅读
0 评论
2 点赞
1
2
3
...
6