【五】gulp之用建立一个代理服务器(解决前端跨域问题)
为什么需要使用代理? 目前,前端发展飞速,前后端分离式开发已经不是新鲜事儿。 1 如果前端只是静态的页面(不需要调用后端的api加载动态数据),那么前端直接在本地开发即可。 即使是前后端分开部署,只需要单独为前端启动一个服务,使用gulp-connect即可。不会?(请戳gulp之用gulp-connect开启一个本地webServer) 2 如果前端需要调用后端提供的接口呢?除非前后端部署在同一个服务器上,否则由于浏览器的限制是没办法跨域请求数据的。真实情况是,我们在本地开发时就需要访问接口,这时后端的程序猿给你的往往是这样一个地址 http://192.168.1.123/controller/action,有人说上传代码到http://192.168.1.123/放在一个目录下不就行了,是啊!可以的。但是好麻烦有没有,调试接口需要传代码上去!!!! 3 如果我的数据是从其他的服务器来的呢?例如我想访问豆瓣的开放接口
1 2 3 4 |
$.post(<span class="hljs-string">'https://api.douban.com/v2/book/1220562'</span>,{},<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{ <span class="hljs-built_in">console</span>.log(data); }) |
豆瓣告诉你,不行!你跨域了! 所以,还是代理来的方便。 代理是个什么鬼? 代理请求通俗点讲,就是把发往 a.com的请求,通过代理服务器发送到b.com。 怎么开启一个代理? 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span class="hljs-comment">//服务端口</span> <span class="hljs-keyword">const</span> PORT=<span class="hljs-number">8000</span>; <span class="hljs-comment">//启动服务的根目录</span> <span class="hljs-keyword">const</span> server_root=<span class="hljs-string">'src'</span> <span class="hljs-comment">//引用gulp</span> <span class="hljs-keyword">var</span> gulp = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp'</span>); <span class="hljs-comment">//引用gulp开启服务的插件</span> <span class="hljs-keyword">var</span> connect = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp-connect'</span>); <span class="hljs-comment">//引用插件 gulp代理中间件插件</span> <span class="hljs-keyword">var</span> proxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http-proxy-middleware'</span>); <span class="hljs-comment">//开启服务</span> gulp.task(<span class="hljs-string">'proxyServer'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{ connect.server({ <span class="hljs-attr">root</span>: [server_root], <span class="hljs-attr">port</span>: PORT, <span class="hljs-attr">middleware</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">connect, opt</span>) </span>{ <span class="hljs-keyword">return</span> [ proxy(<span class="hljs-string">'/api'</span>, { <span class="hljs-attr">target</span>: <span class="hljs-string">'https://api.douban.com/v2'</span>,<span class="hljs-comment">//代理的目标地址</span> changeOrigin:<span class="hljs-literal">true</span>,<span class="hljs-comment">//</span> pathRewrite:{<span class="hljs-comment">//路径重写规则 </span> <span class="hljs-string">'^/api'</span>:<span class="hljs-string">''</span> } }) ] } }); }); |
说明 '/api' =>匹配你要代理的请求地址前缀 target=》你要把请求代理到哪 pathRewrite =》是把你再页面中写的请求地址 某部分 重写为后面的字符串 (例子中讲 请求中写的 /api 重写为 空字符串) 也就是发往 /api/book/1220562的请求最终会被发往 https://api.douban.com/v2/book/1220562 页面写请求时的写法
1 2 3 4 |
$.post(<span class="hljs-string">'/api/book/1220562'</span>,{},<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{ <span class="hljs-built_in">console</span>.log(data); }) |
目录结构 image.png 运行效果 image.png 结语 当然还有其他的方式,比如 node、cros、jsonp、phpheader、nginx设置代理 作者:coder_turbo 链接:https://www.jianshu.com/p/cc543fd0d7c5 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
View Detailsspringboot通过static-locations实现静态资源访问
由于我们的接口是通过springboot一键式打包成jar包发布到服务器的,因此在通过接口上传文件之后,客户端如果还需要再访问该文件,那就需要用到静态资源访问,spring配置如下:
1 2 3 |
spring: resources: static-locations: file:E:\workspace\serverWorkspace\upload\images\photo\20180820,file:/opt/www |
一个是widows下做测试使用,另一个是linux下测试服务器使用。 有时候你会发现可能配置了static-locations但无效,原因可能就是你的目录不对,请仔细检查一下,别问我怎么知道的 如此之后验证即可,如我的: 浏览器输入: localhost:9999/filename ——————— 作者:weixin_34387284 来源:CSDN 原文:https://blog.csdn.net/weixin_34387284/article/details/87066649 版权声明:本文为博主原创文章,转载请附上博文链接!
View DetailsMyBatis实现SaveOrUpdate
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<insert id="saveOrUpdate" > <selectKey keyProperty="count" resultType="int" order="BEFORE"> select count(*) from country where id = #{id} </selectKey> <if test="count > 0"> update country set countryname = #{countryname},countrycode = #{countrycode} where id = #{id} </if> <if test="count==0"> insert into country values(#{id},#{countryname},#{countrycode}) </if> </insert> |
注意如果insert的parameterType是自定义对象的话,对象里需要有count属性,否则会报count属性找不到的错误 from:https://ydlmlh.iteye.com/blog/2236671
View DetailsMyBatis之三:多表联合查询
在这篇文章里面主要讲解如何在mybatis里面使用一对一、一对多、多表联合查询(类似视图)操作的例子。 注:阅读本文前请先大概看一下之前两篇文章。 一、表结构 班级表class,学生表student,班级学生关系表ClassStudent。 这里一个学生只会在一个班级里面,也就是一对一的关系;一个班级有多个学生,也就是一对多的关系。 结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
CREATE TABLE [dbo].[Class]( [class_id] [int] NOT NULL, [class_name] [varchar](50) NOT NULL, CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED ( [class_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] CREATE TABLE [dbo].[ClassStudent]( [class_id] [int] NOT NULL, [student_id] [int] NOT NULL ) ON [PRIMARY] CREATE TABLE [dbo].[Student]( [s_id] [int] NOT NULL, [s_name] [varchar](50) NOT NULL, CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED ( [s_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] |
3张表的数据如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
insert into Class values(1,'三(1)班') insert into Class values(2,'三(2)班') insert into Class values(3,'三(3)班') insert into Class values(4,'三(4)班') insert into Student values(1001,'张三') insert into Student values(1002,'李四') insert into Student values(1003,'赵五') insert into Student values(1004,'王二麻子') insert into ClassStudent values(1,1001) insert into ClassStudent values(1,1003) insert into ClassStudent values(4,1002) insert into ClassStudent values(3,1004) |
二、在原项目下新建一个包com.mybatis.sqljoinrelation,在包里面新建一个sqlMapper.xml的映射文件,在项目的mybatis的配置文件conf.xml中对这个sqlMapper.xml进行注册,注册片段如下:
1 2 3 4 |
<!-- 注册映射文件 --> <mappers> <mapper resource="com/mybatis/sqljoinrelation/sqlMapper.xml" /> </mappers> |
紧接着在原项目下再新建一个包com.mybatis.bean,在里面新建实体类 学生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.mybatis.bean; /** * 学生(临时) */ public class StudentTemp { private int studentid; private String studentname; private Class tempClass; public Class getTempClass() { return tempClass; } public void setTempClass(Class tempClass) { this.tempClass = tempClass; } public int getStudentid() { return studentid; } public void setStudentid(int studentid) { this.studentid = studentid; } public String getStudentname() { return studentname; } public void setStudentname(String studentname) { this.studentname = studentname; } @Override public String toString() { return "StudentTemp [studentid=" + studentid + ", studentname=" + studentname + ", tempClass=" + tempClass + "]"; } } |
班级:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.mybatis.bean; /** * 班级 */ public class Class { private int classid; private String classname; public int getClassid() { return classid; } public void setClassid(int classid) { this.classid = classid; } public String getClassname() { return classname; } public void setClassname(String classname) { this.classname = classname; } @Override public String toString() { return "Class [classid=" + classid + ", classname=" + classname + "]"; } } |
学生班级视图类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.mybatis.bean; public class studentclass { private int s_id; private String s_name; private int class_id; private String class_name; public int getS_id() { return s_id; } public void setS_id(int s_id) { this.s_id = s_id; } public String getS_name() { return s_name; } public void setS_name(String s_name) { this.s_name = s_name; } public int getClass_id() { return class_id; } public void setClass_id(int class_id) { this.class_id = class_id; } public String getClass_name() { return class_name; } public void setClass_name(String class_name) { this.class_name = class_name; } @Override public String toString() { return "studentclass [s_id=" + s_id + ", s_name=" + s_name + ", class_id=" + class_id + ", class_name=" + class_name + "]"; } } |
三、查询操作 1、 一对一,查询学生编号等于1001且他所在班级信息 2、一对多,查询班级编号等于1且包含所有学生信息 3、类似视图查询学生编号等于1001且他所在班级信息 sqlMapper.xml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mybatis.sqljoinrelation.sqlMapper"> <!-- 1、 获取某学生以及该学生所在班级的信息 --> <!-- 可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明, 如果用"*"代替,则mybatis会自动匹配resultMap中提供的列名 --> <select id="getStudentAndClass" parameterType="int" resultMap="studentClassMap"> select c.class_id,c.class_name,s.s_id,s.s_name from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where s.s_id = #{id} </select> <!-- resultMap中的type表示返回什么类型的对象 --> <resultMap type="com.mybatis.bean.StudentTemp" id="studentClassMap"> <!-- property 表示com.mybatis.bean.StudentTemp中的属性; column 表示表中的列名 --> <id property="studentid" column="s_id" /> <result property="studentname" column="s_name" /> <!-- association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称; javaType表示该属性是什么类型对象 --> <association property="tempClass" javaType="com.mybatis.bean.Class"> <!-- property 表示com.mybatis.bean.Class中的属性; column 表示表中的列名 --> <id property="classid" column="class_id" /> <result property="classname" column="class_name" /> </association> </resultMap> <!-- 2、获取某学生以及该学生所在班级的信息,类似视图实现方式 --> <!-- resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样; resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射 --> <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass"> select c.class_id,c.class_name,s.s_id,s.s_name from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where s.s_id = #{id} </select> <!-- 3、获取某班级以及班级里面所有学生的信息 --> <select id="getClassStudents" parameterType="int" resultMap="classStudentsMap"> select * from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where c.class_id = #{id} </select> <resultMap type="com.mybatis.bean.ClassTemp" id="classStudentsMap"> <id property="classid" column="class_id"/> <result property="classname" column="class_name"/> <!-- property表示集合类型属性名称,ofType表示集合中的对象是什么类型 --> <collection property="students" ofType="com.mybatis.bean.Student"> <id property="studentid" column="s_id"/> <result property="studentname" column="s_name"/> </collection> </resultMap> </mapper> |
测试代码如下: 一对一与类似视图查询的代码在一起,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.mybatis.sqljoinrelation; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /** * 一对一 */ public class testonetoone { public static void main(String[] args) { SqlSessionFactory factory = MybatisUtils.getFactory(); SqlSession session = null; try { session = factory.openSession(true); //1、StudentTemp String statement1 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClass"; System.out.println(session.selectOne(statement1, 1001)); //2、用model类型接收数据 String statement2 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClassView"; System.out.println(session.selectOne(statement2, 1001)); } catch (Exception e) { e.printStackTrace(); }finally{ session.close(); } } } |
一对多测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.mybatis.sqljoinrelation; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /** * 一对多 */ public class testonetomany { public static void main(String[] args) { SqlSessionFactory factory = MybatisUtils.getFactory(); SqlSession session = null; try { session = factory.openSession(true); //1、StudentTemp String statement = "com.mybatis.sqljoinrelation.sqlMapper.getClassStudents"; System.out.println(session.selectOne(statement, 1)); } catch (Exception e) { e.printStackTrace(); }finally{ session.close(); } } } |
四、sqlMapper.xml需要说明的问题 1、一对一:<association property="tempClass" javaType="com.mybatis.bean.Class"> association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称; javaType表示该属性是什么类型对象 2、类似视图查询: <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass"> resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样; resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射,其中一对一与一对多都是用resultMap来映射 3、一对多:<collection property="students" ofType="com.mybatis.bean.Student"> collection字面意思是集合,这里专门做一对多关联 ,property表示集合类型属性名称,ofType表示集合中的对象是什么类型 4、<select>select * from …</student>与<select>select 字段1,字段2,字段3… from …</student> 可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明,如果用"*"代替,则mybatis会自动匹配resultMap或者resultType中提供的列名, 如果某对象存在列映射的属性,但是在select 后面找不到这个列,则在返回结果中,该列多映射的值为null。 至此,对于一对一、一对多、视图查询都能很好的解决,主要还是要重点关注第四点说明。 from:https://www.cnblogs.com/wucj/p/5148813.html
View DetailsConsider renaming one of the beans or enabling overriding by setting
1. 报错信息
1 2 3 4 5 6 7 8 |
Description: The bean 'dataSource', defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] and overriding is disabled. Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true |
2. 原因
1 2 |
相同名字不成功 |
3. 解决办法
1 2 3 4 |
main: allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册 |
from:https://blog.csdn.net/weixin_42633131/article/details/84782516
View DetailsAsp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密
本文目录 1. 摘要 2. MD5加密封装 3. AES的加密、解密 4. DES加密/解密 5. 总结 1. 摘要 C#中常用的一些加密和解密方案,如:md5加密、RSA加密与解密和DES加密等,Asp.Net Core 2.0下该如何调整与使用我们以前常用的解加密算法类呢,下面是我整理的MD5加密、AES&DES对称加解密、Encrypt&Decrypt加解密完整实例。希望能给大家提供一些参考和帮助。 2. MD5加密封装 MD5常用加密FormsAuthentication.HashPasswordForStoringInConfigFile在Net Freamwork4.5以后就不在支持,下面整理了32位或16位下的几个方法,以及不同写法,最后一个由从老版本迁移过来,后续淘汰不用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; namespace NC.Common { /// <summary> /// 此类获取md5加密值均为大写,如果要获取小写:MD5Comm.Get32MD5One(xx).ToLower();或完善此类。 /// </summary> public class MD5Comm { #region --Expired code-- ///// <summary> ///// MD5加密 ///// </summary> //public string Md5(string txt) //{ // //return FormsAuthentication.HashPasswordForStoringInConfigFile(txt, "MD5");//此方法nf4.5后不再支持 //} //public string Md5Pass(string pwd) //{ // return Md5(pwd + "Jiahao"); //} #endregion /// <summary> /// 此代码示例通过创建哈希字符串适用于任何 MD5 哈希函数 (在任何平台) 上创建 32 个字符的十六进制格式哈希字符串 /// 官网案例改编 /// </summary> /// <param name="source"></param> /// <returns></returns> public static string Get32MD5One(string source) { using (MD5 md5Hash = MD5.Create()) { byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source)); StringBuilder sBuilder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString("x2")); } string hash = sBuilder.ToString(); return hash.ToUpper(); } } /// <summary> /// 获取16位md5加密 /// </summary> /// <param name="source"></param> /// <returns></returns> public static string Get16MD5One(string source) { using (MD5 md5Hash = MD5.Create()) { byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source)); //转换成字符串,并取9到25位 string sBuilder = BitConverter.ToString(data, 4, 8); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 sBuilder = sBuilder.Replace("-", ""); return sBuilder.ToString().ToUpper(); } } //// <summary> /// </summary> /// <param name="strSource">需要加密的明文</param> /// <returns>返回32位加密结果,该结果取32位加密结果的第9位到25位</returns> public static string Get32MD5Two(string source) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); //获取密文字节数组 byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source)); //转换成字符串,32位 string strResult = BitConverter.ToString(bytResult); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 strResult = strResult.Replace("-", ""); return strResult.ToUpper(); } //// <summary> /// </summary> /// <param name="strSource">需要加密的明文</param> /// <returns>返回16位加密结果,该结果取32位加密结果的第9位到25位</returns> public static string Get16MD5Two(string source) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); //获取密文字节数组 byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source)); //转换成字符串,并取9到25位 string strResult = BitConverter.ToString(bytResult, 4, 8); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 strResult = strResult.Replace("-", ""); return strResult.ToUpper(); } /// <summary> /// 自定义MD5函数,32位,从老版本迁移过来,后续淘汰不用。与Get32MD5One重复 /// </summary> public static string Get32MD5Old(string str) { byte[] b = Encoding.UTF8.GetBytes(str); b = new MD5CryptoServiceProvider().ComputeHash(b); string ret = ""; for (int i = 0; i < b.Length; i++) ret += b[i].ToString("x").PadLeft(2, '0'); return ret.ToUpper(); } } } |
3. AES的加密、解密 上面我们介绍了MD5加密封装,接下来分享给大家供大家参考一下AES加密、解密,AES要注意的是32位密匙。AES 加密解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
using System; using System.IO; using System.Text; using System.Security.Cryptography; namespace NC.Common { /// <summary> /// 加密 /// </summary> public class AES { //默认密钥向量 private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F }; public static string Encode(string encryptString, string encryptKey) { encryptKey = GetSubString(encryptKey,0, 32, ""); encryptKey = encryptKey.PadRight(32, ' '); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32)); rijndaelProvider.IV = Keys; ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor(); byte[] inputData = Encoding.UTF8.GetBytes(encryptString); byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Convert.ToBase64String(encryptedData); } public static string Decode(string decryptString, string decryptKey) { try { decryptKey = GetSubString(decryptKey,0, 32, ""); decryptKey = decryptKey.PadRight(32, ' '); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey); rijndaelProvider.IV = Keys; ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); byte[] inputData = Convert.FromBase64String(decryptString); byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Encoding.UTF8.GetString(decryptedData); } catch { return ""; } } public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString) { string myResult = p_SrcString; Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString); foreach (char c in Encoding.UTF8.GetChars(bComments)) { //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3) if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3')) { //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+")) //当截取的起始位置超出字段串长度时 if (p_StartIndex >= p_SrcString.Length) return ""; else return p_SrcString.Substring(p_StartIndex, ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length); } } if (p_Length >= 0) { byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString); //当字符串长度大于起始位置 if (bsSrcString.Length > p_StartIndex) { int p_EndIndex = bsSrcString.Length; //当要截取的长度在字符串的有效长度范围内 if (bsSrcString.Length > (p_StartIndex + p_Length)) { p_EndIndex = p_Length + p_StartIndex; } else { //当不在有效范围内时,只取到字符串的结尾 p_Length = bsSrcString.Length - p_StartIndex; p_TailString = ""; } int nRealLength = p_Length; int[] anResultFlag = new int[p_Length]; byte[] bsResult = null; int nFlag = 0; for (int i = p_StartIndex; i < p_EndIndex; i++) { if (bsSrcString[i] > 127) { nFlag++; if (nFlag == 3) nFlag = 1; } else nFlag = 0; anResultFlag[i] = nFlag; } if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1)) nRealLength = p_Length + 1; bsResult = new byte[nRealLength]; Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength); myResult = Encoding.Default.GetString(bsResult); myResult = myResult + p_TailString; } } return myResult; } } } |
4. DES加密/解密 除了MD5加密、AES加密/解密之外还经常用到DES加密、解密,注意的是DES的密匙是8位的,这里有家婆MD5加密一起使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
using System; using System.Security.Cryptography; using System.Text; namespace NC.Common { /// <summary> /// DES加密/解密类。 /// </summary> public class DESEncrypt { #region --加密-- /// <summary> /// 加密 /// </summary> /// <param name="Text"></param> /// <returns></returns> public static string Encrypt(string Text) { return Encrypt(Text, "ncmvc"); } /// <summary> /// 加密数据 /// </summary> /// <param name="Text"></param> /// <param name="sKey"></param> /// <returns></returns> public static string Encrypt(string Text, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] inputByteArray; inputByteArray = Encoding.Default.GetBytes(Text); string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8); des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey); des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); foreach (byte b in ms.ToArray()) { ret.AppendFormat("{0:X2}", b); } return ret.ToString(); } catch { return "error"; } } #endregion #region --解密-- /// <summary> /// 解密 /// </summary> /// <param name="Text"></param> /// <returns></returns> public static string Decrypt(string Text) { return Decrypt(Text, "ncmvc"); } /// <summary> /// 解密数据 /// </summary> /// <param name="Text"></param> /// <param name="sKey"></param> /// <returns></returns> public static string Decrypt(string Text, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); int len; len = Text.Length / 2; byte[] inputByteArray = new byte[len]; int x, i; for (x = 0; x < len; x++) { i = Convert.ToInt32(Text.Substring(x * 2, 2), 16); inputByteArray[x] = (byte)i; } string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8); des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey); des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); return Encoding.Default.GetString(ms.ToArray()); } catch { return "error"; } } #endregion } } |
5. 总结 Asp.Net Core 2.0下加解密封装类分享给大家,供参考!文中有不合理之处望告知,欢迎批评指正。以前做项目常用的几种加密方式,在Net Core2.0下经过重新整理,好的延续,不合理方法弃用。相关案例使用方法欢迎大家继续关注《Asp.Net Core 2.0项目实战》系列。 from:https://www.cnblogs.com/oorz/p/8878491.html
View Details【无私分享:ASP.NET CORE 项目实战(第六章)】读取配置文件(一) appsettings.json
简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.config 和 app.config,在 core 中,我们看到了很多的变化,新的配置系统显得更加轻量级,具有更好的扩展性,并且支持多样化的数据源。 博客园对于这个的讲解很多,比如:Artche ,但是,没有点基础看老A的博客还是有些吃力的,对于老A介绍的配置,我也是看的一头雾水,在后面的文章中,我会用像我们这些菜鸟容易接受的方式,重新解释一下。 今天,我们以 appsettings.json 为例,读取一些简单的系统配置。 appsettings.json 在 第二章 中,我们在讲到EF上线文时,在 Startup.cs 添加 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection"))); 已经使用到了 appsettings.json 我们添加一些简单的系统配置,来演示一下读取 appsettings.json: { "ApplicationInsights": { "InstrumentationKey": "" }, "ConnectionStrings": { "SqlServerConnection": "Server=.;Database=db_wkmvc;User ID=sa_wkmvc;Password=123456;" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "ApplicationConfiguration": { //文件上传路径 "FileUpPath": "/upload/", //是否启用单用户登录 "IsSingleLogin": "True", //允许上传的文件格式 "AttachExtension": "gif,jpg,jpeg,png,bmp,rar,zip,doc,docx,xls,xlsx,ppt,pptx,txt,flv,apk,mp4,mpg,ts,mpeg,mp3,bak,pdf", //图片上传最大值KB "AttachImagesize": 12400 } } 我们添加一个配置类 ApplicationConfiguration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
1 public class ApplicationConfiguration 2 { 3 #region 属性成员 4 5 /// <summary> 6 /// 文件上传路径 7 /// </summary> 8 public string FileUpPath { get; set; } 9 /// <summary> 10 /// 是否启用单用户登录 11 /// </summary> 12 public bool IsSingleLogin { get; set; } 13 /// <summary> 14 /// 允许上传的文件格式 15 /// </summary> 16 public string AttachExtension { get; set; } 17 /// <summary> 18 /// 图片上传最大值KB 19 /// </summary> 20 public int AttachImagesize { get; set; } 21 #endregion 22 } |
在 Startup.cs 的 ConfigureServices 添加 services.Configure<ApplicationConfiguration>(Configuration.GetSection("ApplicationConfiguration")); 在Startup.cs的中添加 services.AddTransient<EWS.UI.APP.AppConfigurtaionServices>(); 添加一个领域层 AppConfigurtaionServices public class AppConfigurtaionServices { private readonly IOptions<ApplicationConfiguration> _appConfiguration; public AppConfigurtaionServices(IOptions<ApplicationConfiguration> appConfiguration) { _appConfiguration = appConfiguration; } […]
View DetailsSSO
SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。
View Details阳光不充沛?喜阴又招财的植物推荐
发财树 发财树是常绿乔木,树高8-15米,种於盆栽多不超过2米。掌状复叶,小叶5-7枚,枝条多轮生。花大,长达22.5cm,花瓣条裂,花色有红、白或淡黄色,色泽艳丽。室内观赏多作桩景式盆栽。 富贵竹 金钱树为多年生常绿草本植物,是极为少见的带地下块茎的观叶植物,原产于热带非洲。我国于1997年从荷兰引进,在广州芳村和顺德陈村露面。金钱树叶质厚实、叶色光亮,宛若一挂串连起来的钱币。故以此得名。 摇钱树 叶片颀长,色泽墨绿,属阴生植物,极有富贵气息。 元宝树 元宝树是富贵树中之一,很多家庭都选择元宝树的盆栽,无论是在名字上,还是植物所带来的室内效果,元宝树都是旺家的首选植物之一。元宝树属落叶乔木。又名麻柳、水麻柳。该属约9种,产于北温带。 七叶莲 七叶莲耐寒耐旱性强,是常绿蔓性灌木,分枝多,茎节处生有气生根,掌状复叶互生,有小叶7~9片,长椭圆形,深绿色,叶柄细。花淡黄绿色,秋冬开花,浆果红黄色,春季成熟。适合庭院美化或盆栽。 君子兰 君子兰是着名的温室花卉。我国有从欧洲和日本传入的二个种。前者花小而下垂,称垂笑君子兰;后者花大而向上,称大花君子兰,是目前栽培最普遍的一个种。君子兰叶色苍翠有光泽,花朵向上形似火炬,花色橙红,端庄大方,是美化环境的理想盆花,垂笑君子兰花朵下垂,含蓄深沉,高雅肃穆,另有一番韵味。 万年青 属天南星科,干茎粗壮,树叶厚大,颜色苍翠,极具强盛的生命力。大叶万年青的片片大叶伸展开来,便似一只只肥厚的手掌伸出,向外纳气接福,对家居风水有强大的壮旺作用,所以万年青的叶越大越好,并应保持长绿长青。 蓬莱松 蓬莱松是多年生常绿灌木,极适于盆栽观赏。暖地也可布置花坛。它栽培管理简单,而且耐阴性好,适于中小盆种植用于室内布置,同时也是插花衬叶的极好材料。 from:https://www.d1xz.net/fsml/fszc/art141773.aspx
View Details