当前位置: 编程技术>移动开发
本页文章导读:
▪发一个本人写的鸡肋的jni代码,你能看出有什么有关问题吗 发一个本人写的鸡肋的jni代码,你能看出有什么问题吗?
/*
* 执行对象中的方法
*/
jvalue callMethod(JNIEnv *env, jboolean& hasException, jobject obj, const char *methodName, const char *descriptor, ...)
{
// printf("Me.........
▪ 搬动开发中json协议中的status总结 移动开发中json协议中的status总结
在移动开发中,尤其是基于web端的开发,需要先写好json接口,但是其中涉及到从web端申数据是的一些异常处理,基于此总结一下状态码(status) 一、状态.........
▪ (转)关于将XMPP server部署到Tomcat下的一些有关问题 (转)关于将XMPP server部署到Tomcat上的一些问题
在XMPP消息推送这个问题上,网上已经有很多资料了,本人觉得很好的一篇资料是:http://www.iteye.com/topic/1117043 提供了一个连接下载源码:http://1.........
[1]发一个本人写的鸡肋的jni代码,你能看出有什么有关问题吗
来源: 互联网 发布时间: 2014-02-18
发一个本人写的鸡肋的jni代码,你能看出有什么问题吗?
/*
* 执行对象中的方法
*/
jvalue callMethod(JNIEnv *env, jboolean& hasException, jobject obj, const char *methodName, const char *descriptor, ...)
{
// printf("Method");
jvalue result;
jobject refobj;
jclass targetcls;
jmethodID mid;
const char *p = descriptor;
//判断本地版本
// if(env->EnsureLocalCapacity(100) != JNI_OK)
// {
// printf("EnsureLocalCapacity == null");
// goto error;
// }
printf("Method11");
refobj = env->NewLocalRef(obj);
printf("Method33");
targetcls = env->GetObjectClass(refobj);
printf("Method1");
mid = env->GetMethodID(targetcls, methodName, descriptor);
if(mid == NULL){
printf("mid == null");
env->DeleteLocalRef(targetcls);
env->DeleteLocalRef(refobj);
goto error;
}
while(*p != ')') p++;
p++;
va_list ap;
va_start(ap, descriptor);
// printf("Method2");
switch(*p){
case 'V':
env->CallVoidMethodV(refobj, mid, ap);
break;
case '[':
case 'L':
result.l = env->CallObjectMethodV(refobj, mid, ap);
break;
case 'Z':
result.z = env->CallBooleanMethodV(refobj, mid, ap);
break;
case 'B':
result.b = env->CallByteMethodV(refobj, mid, ap);
break;
case 'C':
result.c = env->CallCharMethodV(refobj, mid, ap);
break;
case 'S':
result.s = env->CallShortMethodV(refobj, mid, ap);
break;
case 'I':
result.i = env->CallIntMethodV(refobj, mid, ap);
break;
case 'J':
result.j = env->CallLongMethodV(refobj, mid, ap);
break;
case 'F':
result.f = env->CallFloatMethodV(refobj, mid, ap);
break;
case 'D':
result.d = env->CallDoubleMethodV(refobj, mid, ap);
break;
}
va_end(ap);
// printf("Method3");
env->DeleteLocalRef(targetcls);
env->DeleteLocalRef(refobj);
error:
if(env->ExceptionOccurred())
{
printf("Method4");
hasException = env->ExceptionCheck();
// env->ExceptionDescribe();
// env->ExceptionClear();
// env->ThrowNew(targetcls, "error");
}
return result;
}
[2] 搬动开发中json协议中的status总结
来源: 互联网 发布时间: 2014-02-18
移动开发中json协议中的status总结
在移动开发中,尤其是基于web端的开发,需要先写好json接口,但是其中涉及到从web端申数据是的一些异常处理,基于此总结一下状态码(status)
一、状态码概况:
二、信息
三、成功
四、重定向
五、客户端错误
六、服务端错误
七、除以上的其他
6** 7** 8** 9** 等可以自己根据需求自定义
在移动开发中,尤其是基于web端的开发,需要先写好json接口,但是其中涉及到从web端申数据是的一些异常处理,基于此总结一下状态码(status)
一、状态码概况:
0**:未被始化
1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败
二、信息
100——客户必须继续发出请求(Continue)
101——客户要求服务器根据请求转换HTTP协议版本(Switching protocols)
三、成功
200——交易成功(OK)
201——提示知道新文件的URL(/blog_article/Created/index.html)
202——接受和处理、但处理未完成(Accepted)
203——返回信息不确定或不完整(Non-Authoritative Information)
204——请求收到,但返回信息为空(No Content)
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件(Reset Content)
206——服务器已经完成了部分用户的GET请求(Partial Content)
四、重定向
300——请求的资源可在多处得到(Multiple Choices)
301——删除请求数据(Moved Permanently)
302——在其他地址发现了请求数据(Found)
303——建议客户访问其他URL或访问方式(See Other)
304——客户端已经执行了GET,但文件未变化(Not Modified)
305——请求的资源必须从服务器指定的地址得到(Use Proxy)
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除(Temporary Redirect)五、客户端错误
400——错误请求,如语法错误(Bad Request)
401——请求授权失败(Unauthorized)
402——保留有效ChargeTo头响应(Payment Required)
403——请求不允许(由于服务器上文件或目录的权限设置导致资源不可用)(Forbidden)
404——没有发现文件、查询或URl(/blog_article/没有找到指定的资源/index.html)(Not Found)
405——用户在Request-Line字段定义的方法不允许(Method Not Allowed)
406——根据用户发送的Accept拖,请求资源不可访问(Not Acceptable)
407——类似401,用户必须首先在代理服务器上得到授权(Proxy Authentication Required)
408——客户端没有在用户指定的饿时间内完成请求(Request Timeout)
409——对当前资源状态,请求不能完成(Conflict)
410——服务器上不再有此资源且无进一步的参考地址(Gone)
411——服务器拒绝用户定义的Content-Length属性请求(Length Required)
412——一个或多个请求头字段在当前请求中错误(Precondition Failed)
413——请求的资源大于服务器允许的大小(Request Entity Too Large)
414——请求的资源URL长于服务器允许的长度(Request-URI Too Long)
415——请求资源不支持请求项目格式(Unsupported Media Type)
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段(Requested Range Not Suitable)
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求(Expectation Failed)
六、服务端错误
500——服务器产生内部错误(Internal Server Error)
501——服务器不支持请求的函数(Not Implemented)
502——服务器暂时不可用,有时是为了防止发生系统过载(Bad Gateway)
503——服务器过载或暂停维修(Service Unavailable)
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长(Gateway Timeout)
505——服务器不支持或拒绝支请求头中指定的HTTP版本(HTTP Version Not Supported )
七、除以上的其他
6** 7** 8** 9** 等可以自己根据需求自定义
[3] (转)关于将XMPP server部署到Tomcat下的一些有关问题
来源: 互联网 发布时间: 2014-02-18
(转)关于将XMPP server部署到Tomcat上的一些问题
在XMPP消息推送这个问题上,网上已经有很多资料了,本人觉得很好的一篇资料是:http://www.iteye.com/topic/1117043 提供了一个连接下载源码:http://115.com/file/bhkfse3i#%20Androidpn.rar 很感谢前辈们的研究结果。 在源码的使用过程中要注意的地方有两点,网上的那篇资料好像忽略了一个重要的地方,就是要改resources文件夹下面的jdbc.properties,将里面关于数据库的配置改为自己的,另一个需要注意的地方就是改android端的ip了。
在项目部署到tomcat下之后,发现了不少的bug,其中一个就是当tomcat重新启动,客户端的连接将断开,不能进行自动重连。
对于这个BUG,我们可以在Androidpn-clieng下的XmppManager这个类中做简要的处理即可修改。源码如下:
新添加代码450-454行和477行
还有一个问题是:当客户端的用户有不在线的时候,消息应怎么进行推送,是直接忽略呢还是下次登录的时候在进行推送,想qq那样,很显然对已一个具体的实用项目来说是不能忽略的,那么怎么进行消息的离线推送呢,下次告诉大家,因为我现在还没解决,不过快了。和大家说下我的思路吧:在androidpn服务端有一个UserController这个类,源码如下:
该源码里面有用户是否在线的判断,我们只要将用户的列表取出来,如果用户在线就将消息进行推送,如果有不在线的用户,我们就把该消息放到缓存中(也可以放到数据库中更加保险),当然为了防止用户过长没有登陆系统,导致下次登录时出现过多托送过来的消息,我们还可以在服务端进行设置时间,比如服务端只缓存近N天的消息,利用
这两句代码应该可以完成,本人没尝试过,还不知道。效果如如下:
在项目部署到tomcat下之后,发现了不少的bug,其中一个就是当tomcat重新启动,客户端的连接将断开,不能进行自动重连。
对于这个BUG,我们可以在Androidpn-clieng下的XmppManager这个类中做简要的处理即可修改。源码如下:
/*
* Copyright (C) 2010 Moduad Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.androidpn.client;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Future;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Registration;
import org.jivesoftware.smack.provider.ProviderManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Handler;
import android.util.Log;
/**
* This class is to manage the XMPP connection between client and server.
*
* @author Sehwan Noh (devnoh@gmail.com)
*/
public class XmppManager {
private static final String LOGTAG = LogUtil.makeLogTag(XmppManager.class);
private static final String XMPP_RESOURCE_NAME = "AndroidpnClient";
private Context context;
private NotificationService.TaskSubmitter taskSubmitter;
private NotificationService.TaskTracker taskTracker;
private SharedPreferences sharedPrefs;
private String xmppHost;
private int xmppPort;
private XMPPConnection connection;
private String username;
private String password;
private ConnectionListener connectionListener;
private PacketListener notificationPacketListener;
private Handler handler;
private List<Runnable> taskList;
private boolean running = false;
private Future<?> futureTask;
private Thread reconnection;
public XmppManager(NotificationService notificationService) {
context = notificationService;
taskSubmitter = notificationService.getTaskSubmitter();
taskTracker = notificationService.getTaskTracker();
sharedPrefs = notificationService.getSharedPreferences();
xmppHost = sharedPrefs.getString(Constants.XMPP_HOST, "localhost");
xmppPort = sharedPrefs.getInt(Constants.XMPP_PORT, 5222);
username = sharedPrefs.getString(Constants.XMPP_USERNAME, "");
password = sharedPrefs.getString(Constants.XMPP_PASSWORD, "");
connectionListener = new PersistentConnectionListener(this);
notificationPacketListener = new NotificationPacketListener(this);
handler = new Handler();
taskList = new ArrayList<Runnable>();
reconnection = new ReconnectionThread(this);
}
public Context getContext() {
return context;
}
public void connect() {
Log.d(LOGTAG, "connect()...");
submitLoginTask();
}
public void disconnect() {
Log.d(LOGTAG, "disconnect()...");
terminatePersistentConnection();
}
public void terminatePersistentConnection() {
Log.d(LOGTAG, "terminatePersistentConnection()...");
Runnable runnable = new Runnable() {
final XmppManager xmppManager = XmppManager.this;
public void run() {
if (xmppManager.isConnected()) {
Log.d(LOGTAG, "terminatePersistentConnection()... run()");
xmppManager.getConnection().removePacketListener(
xmppManager.getNotificationPacketListener());
xmppManager.getConnection().disconnect();
}
xmppManager.runTask();
}
};
addTask(runnable);
}
public XMPPConnection getConnection() {
return connection;
}
public void setConnection(XMPPConnection connection) {
this.connection = connection;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public ConnectionListener getConnectionListener() {
return connectionListener;
}
public PacketListener getNotificationPacketListener() {
return notificationPacketListener;
}
public void startReconnectionThread() {
synchronized (reconnection) {
if (!reconnection.isAlive()) {
reconnection.setName("Xmpp Reconnection Thread");
reconnection.start();
}
}
}
public Handler getHandler() {
return handler;
}
public void reregisterAccount() {
removeAccount();
submitLoginTask();
runTask();
}
public List<Runnable> getTaskList() {
return taskList;
}
public Future<?> getFutureTask() {
return futureTask;
}
public void runTask() {
Log.d(LOGTAG, "runTask()...");
synchronized (taskList) {
running = false;
futureTask = null;
if (!taskList.isEmpty()) {
Runnable runnable = (Runnable) taskList.get(0);
taskList.remove(0);
running = true;
futureTask = taskSubmitter.submit(runnable);
if (futureTask == null) {
taskTracker.decrease();
}
}
}
taskTracker.decrease();
Log.d(LOGTAG, "runTask()...done");
}
private String newRandomUUID() {
String uuidRaw = UUID.randomUUID().toString();
return uuidRaw.replaceAll("-", "");
}
private boolean isConnected() {
return connection != null && connection.isConnected();
}
private boolean isAuthenticated() {
return connection != null && connection.isConnected()
&& connection.isAuthenticated();
}
private boolean isRegistered() {
return sharedPrefs.contains(Constants.XMPP_USERNAME)
&& sharedPrefs.contains(Constants.XMPP_PASSWORD);
}
private void submitConnectTask() {
Log.d(LOGTAG, "submitConnectTask()...");
addTask(new ConnectTask());
}
private void submitRegisterTask() {
Log.d(LOGTAG, "submitRegisterTask()...");
submitConnectTask();
addTask(new RegisterTask());
}
private void submitLoginTask() {
Log.d(LOGTAG, "submitLoginTask()...");
submitRegisterTask();
addTask(new LoginTask());
}
private void addTask(Runnable runnable) {
Log.d(LOGTAG, "addTask(runnable)...");
taskTracker.increase();
synchronized (taskList) {
if (taskList.isEmpty() && !running) {
running = true;
futureTask = taskSubmitter.submit(runnable);
if (futureTask == null) {
taskTracker.decrease();
}
} else {
taskList.add(runnable);
}
}
Log.d(LOGTAG, "addTask(runnable)... done");
}
private void removeAccount() {
Editor editor = sharedPrefs.edit();
editor.remove(Constants.XMPP_USERNAME);
editor.remove(Constants.XMPP_PASSWORD);
editor.commit();
}
/**
* A runnable task to connect the server.
*/
private class ConnectTask implements Runnable {
final XmppManager xmppManager;
private ConnectTask() {
this.xmppManager = XmppManager.this;
}
public void run() {
Log.i(LOGTAG, "ConnectTask.run()...");
if (!xmppManager.isConnected()) {
// Create the configuration for this new connection
ConnectionConfiguration connConfig = new ConnectionConfiguration(
xmppHost, xmppPort);
// connConfig.setSecurityMode(SecurityMode.disabled);
connConfig.setSecurityMode(SecurityMode.required);
connConfig.setSASLAuthenticationEnabled(false);
connConfig.setCompressionEnabled(false);
XMPPConnection connection = new XMPPConnection(connConfig);
xmppManager.setConnection(connection);
try {
// Connect to the server
connection.connect();
Log.i(LOGTAG, "XMPP connected successfully");
// packet provider
ProviderManager.getInstance().addIQProvider("notification",
"androidpn:iq:notification",
new NotificationIQProvider());
} catch (XMPPException e) {
Log.e(LOGTAG, "XMPP connection failed", e);
}
xmppManager.runTask();
} else {
Log.i(LOGTAG, "XMPP connected already");
xmppManager.runTask();
}
}
}
/**
* A runnable task to register a new user onto the server.
*/
private class RegisterTask implements Runnable {
final XmppManager xmppManager;
private RegisterTask() {
xmppManager = XmppManager.this;
}
public void run() {
Log.i(LOGTAG, "RegisterTask.run()...");
//如果账号不存在的话,随机生成一个uuid的用户名和mima
if (!xmppManager.isRegistered()) {
final String newUsername = newRandomUUID();
final String newPassword = newRandomUUID();
// final String newUsername = "af100042487d4b06a49adda8c3a82d41";
// final String newPassword = "af100042487d4b06a49adda8c3a82d41";
Registration registration = new Registration();
PacketFilter packetFilter = new AndFilter(new PacketIDFilter(
registration.getPacketID()), new PacketTypeFilter(
IQ.class));
PacketListener packetListener = new PacketListener() {
public void processPacket(Packet packet) {
Log.d("RegisterTask.PacketListener",
"processPacket().....");
Log.d("RegisterTask.PacketListener", "packet="
+ packet.toXML());
if (packet instanceof IQ) {
IQ response = (IQ) packet;
if (response.getType() == IQ.Type.ERROR) {
if (!response.getError().toString().contains(
"409")) {
Log.e(LOGTAG,
"Unknown error while registering XMPP account! "
+ response.getError()
.getCondition());
}
} else if (response.getType() == IQ.Type.RESULT) {
xmppManager.setUsername(newUsername);
xmppManager.setPassword(newPassword);
Log.d(LOGTAG, "username=" + newUsername);
Log.d(LOGTAG, "password=" + newPassword);
Editor editor = sharedPrefs.edit();
editor.putString(Constants.XMPP_USERNAME,
newUsername);
editor.putString(Constants.XMPP_PASSWORD,
newPassword);
editor.commit();
Log
.i(LOGTAG,
"Account registered successfully");
xmppManager.runTask();
}
}
}
};
connection.addPacketListener(packetListener, packetFilter);
registration.setType(IQ.Type.SET);
// registration.setTo(xmppHost);
// Map<String, String> attributes = new HashMap<String, String>();
// attributes.put("username", rUsername);
// attributes.put("password", rPassword);
// registration.setAttributes(attributes);
registration.addAttribute("username", newUsername);
registration.addAttribute("password", newPassword);
connection.sendPacket(registration);
} else {
Log.i(LOGTAG, "Account registered already");
xmppManager.runTask();
}
}
}
/**
* A runnable task to log into the server.
*/
private class LoginTask implements Runnable {
final XmppManager xmppManager;
private LoginTask() {
this.xmppManager = XmppManager.this;
}
public void run() {
Log.i(LOGTAG, "LoginTask.run()...");
if (!xmppManager.isAuthenticated()) {
Log.d(LOGTAG, "username=" + username);
Log.d(LOGTAG, "password=" + password);
try {
xmppManager.getConnection().login(
xmppManager.getUsername(),
xmppManager.getPassword(), XMPP_RESOURCE_NAME);
Log.d(LOGTAG, "Loggedn in successfully");
// connection listener
if (xmppManager.getConnectionListener() != null) {
xmppManager.getConnection().addConnectionListener(
xmppManager.getConnectionListener());
}
// packet filter
PacketFilter packetFilter = new PacketTypeFilter(
NotificationIQ.class);
// packet listener
PacketListener packetListener = xmppManager
.getNotificationPacketListener();
connection.addPacketListener(packetListener, packetFilter);
//判断是否处于连接状态(添加)
if(!getConnection().isConnected())
{
xmppManager.runTask();
}
xmppManager.runTask();
} catch (XMPPException e) {
Log.e(LOGTAG, "LoginTask.run()... xmpp error");
Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: "
+ e.getMessage());
String INVALID_CREDENTIALS_ERROR_CODE = "401";
String errorMessage = e.getMessage();
if (errorMessage != null
&& errorMessage
.contains(INVALID_CREDENTIALS_ERROR_CODE)) {
xmppManager.reregisterAccount();
return;
}
xmppManager.startReconnectionThread();
} catch (Exception e) {
Log.e(LOGTAG, "LoginTask.run()... other error");
Log.e(LOGTAG, "Failed to login to xmpp server. Caused by: "
+ e.getMessage());
xmppManager.startReconnectionThread();
}
//添加
xmppManager.runTask();
} else {
Log.i(LOGTAG, "Logged in already");
xmppManager.runTask();
}
}
}
}
新添加代码450-454行和477行
还有一个问题是:当客户端的用户有不在线的时候,消息应怎么进行推送,是直接忽略呢还是下次登录的时候在进行推送,想qq那样,很显然对已一个具体的实用项目来说是不能忽略的,那么怎么进行消息的离线推送呢,下次告诉大家,因为我现在还没解决,不过快了。和大家说下我的思路吧:在androidpn服务端有一个UserController这个类,源码如下:
View Code
/*
* Copyright (C) 2010 Moduad Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.androidpn.server.console.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.androidpn.server.model.User;
import org.androidpn.server.service.ServiceLocator;
import org.androidpn.server.service.UserService;
import org.androidpn.server.xmpp.presence.PresenceManager;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
/**
* A controller class to process the user related requests.
*
* @author Sehwan Noh (devnoh@gmail.com)
*/
public class UserController extends MultiActionController {
private UserService userService;
public UserController() {
userService = ServiceLocator.getUserService();
}
//用户列表
public ModelAndView list(HttpServletRequest request,
HttpServletResponse response) throws Exception {
PresenceManager presenceManager = new PresenceManager();
List<User> userList = userService.getUsers();
for (User user : userList) {
if (presenceManager.isAvailable(user)) {
// Presence presence = presenceManager.getPresence(user);
user.setOnline(true);
} else {
user.setOnline(false);
}
// logger.debug("user.online=" + user.isOnline());
}
ModelAndView mav = new ModelAndView();
mav.addObject("userList", userList);
mav.setViewName("user/list");
return mav;
}
}
该源码里面有用户是否在线的判断,我们只要将用户的列表取出来,如果用户在线就将消息进行推送,如果有不在线的用户,我们就把该消息放到缓存中(也可以放到数据库中更加保险),当然为了防止用户过长没有登陆系统,导致下次登录时出现过多托送过来的消息,我们还可以在服务端进行设置时间,比如服务端只缓存近N天的消息,利用
session.getCreationDate(); session.getLastActiveDate();
这两句代码应该可以完成,本人没尝试过,还不知道。效果如如下:
最新技术文章: