首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

基于hi-nginx的web开发(python篇)——cookie和会话管理

hi-nginx通过redis管理会话。 要开启管理,需要做三件事。 第一件开启userid: userid on; userid_name SESSIONID; userid_domain localhost; userid_path /; userid_expires 300s; 这个功能是nginx内建的,可以直接使用。需要注意的是,hi-nginx只认识SESSIONID的userid_name。 第二件是配置redis服务器: hi_redis_host 127.0.0.1; hi_redis_port 6379; 当然,你应该先安装redis并确保它运行。 第三件是在location段开启会话管理: location / { hi_need_session on; hi_session_expires 300s; hi_python_script python/index.py; } 整个nginx配置写下来,就是: 1 server { 2 listen 8080; 3 server_name localhost; 4 5 userid on; 6 userid_name SESSIONID; 7 userid_domain localhost; 8 userid_path /; 9 userid_expires 300s; 10 11 hi_redis_host 127.0.0.1; 12 hi_redis_port 6379; 13 14 15 location / { 16 hi_need_cache off; 17 hi_cache_expires 5s; 18 19 hi_need_session on; 20 hi_session_expires 300s; 21 hi_python_script python/index.py; 22 } 23 } 需要注意是,应该确保hi_session_expires和userid_expires的值保持一致。 配置写完后,记得reload或者restart nginx。 接下来就是使用会话管理的api了。 说来太简单,都不好意思写出来,用req.has_session,req.get_session和res.session即可: @app.route('^/session/?$',['GET']) def session(req,res,param): k='test' v=0 if req.has_session(k): v=int(req.get_session(k)) res.session(k,str(v+1)) else: res.session(k,str(v)) res.content('{}={}'.format(k,v)) res.status(200) 那么,cookie怎么办?人们使用cookie的一大用途建立会话机制。上文已经把会话管理的使用说清楚了。所以使用hi.py框架时不需要特别留意cookie的管理。当然,如果你想自己管理cookie,hi-nginx也提供req.has_cookie和req.get_cookie两个只读api。如果要写api,可以使用res.header来写。比如: 在location段中添加hi_need_cookies on 1 location / { 2 hi_need_cache off; 3 hi_cache_expires 5s; 4 hi_need_cookies on; 5 hi_need_session on; 6 hi_session_expires 300s; 7 hi_python_script python/index.py; 8 } 在操作函数中在添加相关操作: @app.route('^/session/?$',['GET']) def session(req,res,param): k='test' v=0 if req.has_session(k): v=int(req.get_session(k)) res.session(k,str(v+1)) else: res.session(k,str(v)) cv=v if req.has_cookie(k): cv=int(req.get_cookie(k)) res.header('Set-Cookie','{}={};Path={};Domain={}'.format(k,cv+1,'/','localhost')) else: res.header('Set-Cookie','{}={};Path={};Domain={}'.format(k,cv,'/','localhost')) res.content('session:{0}={1},cookie:{0}={2}'.format(k,v,cv)) res.status(200) 如上所见,在hi.py中操控和管理cookie和会话是非常方便的,用来写个登陆或者购物车什么的,配合hi.py的jinja2模板引擎,简直易如反掌。

优秀的个人博客,低调大师

基于hi-nginx的web开发(python篇)——utf-8编码

一致地utf-8编码,非常重要。对python2而言,尤其如此。 如果在hi-nginx中使用的是python2,同时又需要无障碍地使用中日韩等文字,那么一定不要忘记使用: #-*- coding:utf-8 -*- 同时,任何模板文件,也应该使用utf-8编码。这样就可以避免许多无谓的错误了。 因为hi.py框架在引入时,会自动检查sys模块的默认编码,并重设置为utf-8编码: if sys.version_info.major < 3: reload(sys) sys.setdefaultencoding('utf-8') 所以使用hi.py框架时,务必牢记一切归于utf-8。

优秀的个人博客,低调大师

Android NDK开发系列教程3:基本方法调用及传参(续)

终于建了一个自己个人小站:https://huangtianyu.gitee.io,以后优先更新小站博客,欢迎进站,O(∩_∩)O~~ 上一节主要讲解Java向native传参,下面主要讲解从native传相应的数据到java层。 接着上一节,下面主要讲解内容如下: 1. native向java返回字符串类型 2. native向java返回java对象 3. native向java返回数组类型 4. native向Java返回List对象 对于上面的每个都给出对应的例子。 本节所有案例代码均已放到GitHub上,欢迎下载: https://github.com/huangtianyu/JNILearnCourse 1. native向java返回字符串类型 传基本数据类型很简单,是什么就传什么就行。传字符串类型也很简单,具体jni代码如下: extern "C" JNIEXPORT jstring JNICALL Java_zqc_com_example_NativeTest_jni2javaMethod1(JNIEnv *env, jobject instance) { //jstring NewStringUTF(const char* bytes),jstring NewString(const jchar* unicodeChars, jsize len) char *returnValue = "你在native做你的操作后,生成char*后,通过env->NewStringUTF即可返回Java的String类型"; return env->NewStringUTF(returnValue); } 其中最主要用的是以下几个方法: //创建Unicode格式的jstring串 jstring NewString(const jchar* unicodeChars, jsize len) { return functions->NewString(this, unicodeChars, len); } //获取jstring长度 jsize GetStringLength(jstring string) { return functions->GetStringLength(this, string); } //获取jstring对应的字符串,isCopy表示是否拷贝生成副本。 //这个函数返回一个指向特定jstring中字符顺序的指针,该指针保持有效直到ReleaseStringChars函数被调用: const jchar* GetStringChars(jstring string, jboolean* isCopy) { return functions->GetStringChars(this, string, isCopy); } //释放指针 void ReleaseStringChars(jstring string, const jchar* chars) { functions->ReleaseStringChars(this, string, chars); } ////创建UTF-8格式的jstring串 jstring NewStringUTF(const char* bytes) { return functions->NewStringUTF(this, bytes); } //获取utf字符串的长度 jsize GetStringUTFLength(jstring string) { return functions->GetStringUTFLength(this, string); } //同GetStringChars const char* GetStringUTFChars(jstring string, jboolean* isCopy) { return functions->GetStringUTFChars(this, string, isCopy); } //同ReleaseStringChars void ReleaseStringUTFChars(jstring string, const char* utf) { functions->ReleaseStringUTFChars(this, string, utf); } 以上是处理字符串常用的一些方法。 2 native向java返回java对象 具体看native的代码如下: extern "C" JNIEXPORT jobject JNICALL Java_zqc_com_example_NativeTest_jni2javaMethod2(JNIEnv *env, jobject instance) { jclass pcls = env->FindClass("zqc/com/example/Person"); jmethodID constructor = env->GetMethodID(pcls, "<init>", "()V"); jmethodID setIdMid = env->GetMethodID(pcls, "setId", "(J)V"); jmethodID setNameMid = env->GetMethodID(pcls, "setName", "(Ljava/lang/String;)V"); jmethodID setAgeMid = env->GetMethodID(pcls, "setName", "(I)V"); jobject person = env->NewObject(pcls, constructor); env->CallVoidMethod(person, setIdMid, 100L); env->CallVoidMethod(person, setNameMid, env->NewStringUTF("天宇")); env->CallVoidMethod(person, setAgeMid, 18); return person; } 常用新建Object的方法由以下几个: //将传递给构造函数的所有参数紧跟着放在 methodID 参数的后面。NewObject() 收到这些参数后,将把它们传给所要调用的Java 方法。 jobject NewObject(jclass clazz, jmethodID methodID, ...) { va_list args; va_start(args, methodID); jobject result = functions->NewObjectV(this, clazz, methodID, args); va_end(args); return result; } //将传递给构造函数的所有参数放在 va_list 类型的参数 args 中,该参数紧跟着放在 methodID 参数的后面。NewObject() 收到这些参数后,将把它们传给所要调用的 Java 方法。 jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) { return functions->NewObjectV(this, clazz, methodID, args); } //将传递给构造函数的所有参数放在jvalues类型的数组args中,该数组紧跟着放在methodID参数的后面。NewObject() 收到数组中的这些参数后,将把它们传给所要调用的 Java 方法。 jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) { return functions->NewObjectA(this, clazz, methodID, args); } //测试对象是否为某个类的实例。 jboolean IsInstanceOf(jobject obj, jclass clazz) { return functions->IsInstanceOf(this, obj, clazz); } //测试两个引用是否引用同一 Java 对象。 jboolean IsSameObject(jobject ref1, jobject ref2) { return functions->IsSameObject(this, ref1, ref2); } //分配新 Java 对象而不调用该对象的任何构造函数。返回该对象的引用。 //该方法会抛出:InstantiationException:如果该类为一个接口或抽象类。OutOfMemoryError:如果系统内存不足。 jobject AllocObject(jclass clazz) { return functions->AllocObject(this, clazz); } //判断某个Object是否是某个class的具体实例 jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); 3 native向java返回数组类型 3.1 基本类型数组 这里直接看native层代码如下: extern "C" JNIEXPORT jintArray JNICALL Java_zqc_com_example_NativeTest_jni2javaMethod3(JNIEnv *env, jobject instance) { int nat[] = {2, 1, 4, 3, 5}; jintArray jnat = env->NewIntArray(5); env->SetIntArrayRegion(jnat, 0, 5, nat); return jnat; } 基本数据类型数组都有相应的env->NewXXXArray(jsize length);通过该方法可以生成对应的数组。 jbooleanArray NewBooleanArray(jsize length) { return functions->NewBooleanArray(this, length); } jbyteArray NewByteArray(jsize length) { return functions->NewByteArray(this, length); } jcharArray NewCharArray(jsize length) { return functions->NewCharArray(this, length); } jshortArray NewShortArray(jsize length) { return functions->NewShortArray(this, length); } jintArray NewIntArray(jsize length) { return functions->NewIntArray(this, length); } jlongArray NewLongArray(jsize length) { return functions->NewLongArray(this, length); } jfloatArray NewFloatArray(jsize length) { return functions->NewFloatArray(this, length); } jdoubleArray NewDoubleArray(jsize length) { return functions->NewDoubleArray(this, length); } 在生成了对应的数组后,可以通过setXXXArrayRegion(jxxxArray array, jsize start, jsize len, const jchar* buf)来填充数组 void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, const jboolean* buf) { functions->SetBooleanArrayRegion(this, array, start, len, buf); } void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte* buf) { functions->SetByteArrayRegion(this, array, start, len, buf); } void SetCharArrayRegion(jcharArray array, jsize start, jsize len, const jchar* buf) { functions->SetCharArrayRegion(this, array, start, len, buf); } void SetShortArrayRegion(jshortArray array, jsize start, jsize len, const jshort* buf) { functions->SetShortArrayRegion(this, array, start, len, buf); } void SetIntArrayRegion(jintArray array, jsize start, jsize len, const jint* buf) { functions->SetIntArrayRegion(this, array, start, len, buf); } void SetLongArrayRegion(jlongArray array, jsize start, jsize len, const jlong* buf) { functions->SetLongArrayRegion(this, array, start, len, buf); } void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, const jfloat* buf) { functions->SetFloatArrayRegion(this, array, start, len, buf); } void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, const jdouble* buf) { functions->SetDoubleArrayRegion(this, array, start, len, buf); } 3.2 对象类型数组 直接看native代码: extern "C" JNIEXPORT jobjectArray JNICALL Java_zqc_com_example_NativeTest_jni2javaMethod4(JNIEnv *env, jobject instance) { jclass cls = env->FindClass("zqc/com/example/Person"); jmethodID cMid = env->GetMethodID(cls, "<init>", "()V"); jclass pcls = env->FindClass("zqc/com/example/Person"); jmethodID cmid = env->GetMethodID(pcls, "<init>", "()V"); jmethodID setNameMid = env->GetMethodID(pcls, "setName", "(Ljava/lang/String;)V"); jmethodID setAgeMid = env->GetMethodID(pcls, "setAge", "(I)V"); jobject obj = env->NewObject(pcls, cmid); env->CallVoidMethod(obj, setNameMid, env->NewStringUTF("天宇")); int len = 3; jobjectArray joa = env->NewObjectArray(len, cls, obj); for (int i = 0; i < len; ++i) { jobject tmp = env->GetObjectArrayElement(joa,i); env->CallVoidMethod(tmp, setAgeMid, i + 10); } return joa; } 其在native生成的方法是 jobjectArray joa = env->NewObjectArray(len, cls, obj); //第一个参数表示生成的长度,第二参数表示里面元素的对象类,第三个表示原始初始化时的值。在生成后每个元素都是该值。 jobjectArray NewObjectArray(jsize length, jclass elementClass, jobject initialElement) { return functions->NewObjectArray(this, length, elementClass, initialElement); } 4 native向Java返回List对象 直接看native代码如下: extern "C" JNIEXPORT jobject JNICALL Java_zqc_com_example_NativeTest_jni2javaMethod5(JNIEnv *env, jobject instance) { jclass listCls = env->FindClass("java/util/ArrayList");//获得ArrayList类引用 jmethodID listCon = env->GetMethodID(listCls, "<init>", "()V");//获取构造函数的methodID jmethodID addMid = env->GetMethodID(listCls,"add","(Ljava/lang/Object;)Z");//获取add函数的methodID jobject listObj = env->NewObject(listCls, listCon);//利用NewObject创建一个ArrayList对象 jobject jperon = Java_zqc_com_example_NativeTest_jni2javaMethod2(env, instance);//利用上面方法新建一个Person对象 env->CallBooleanMethod(listObj, addMid, jperon);//在listObj中add一个Person对象 //返回ArrayList的对象 return listObj; } 对应jni而言,List,ArrayList以及Map,HashMap,Set,HashSet都只是一个Object,对应于jni而言也就都是jobject,操作jobject都可以用最开始介绍的方法。 总结 jni里面的方法很多,多用用就熟悉了。常用的上面都有,自己之前还总结了很多常用的类型转换函数。以后有时间再写篇博客分享下。不会就要查手册:http://www.ceeger.com/Script/AndroidJNI/AndroidJNI.html

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册