我正在开发一个拥有主机和客户端的项目,主机可以向客户端发送命令(通过套接字).
我确定使用JSON进行通信是最好的.
例如:
{
"method" : "toasty",
"params" : ["hello world", true]
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,当此JSON字符串发送到客户端时,它将被处理,并且客户端内的合适方法将如下运行:
public abstract class ClientProcessor {
public abstract void toasty(String s, boolean bool);
public abstract void shutdown(int timer);
private Method[] methods = getClass().getDeclaredMethods();
public void process(String data) {
try {
JSONObject json = new JSONObject(data);
String methodName = (String) json.get("method");
if (methodName.equals("process"))
return;
for (int i = 0; i < methods.length; i++)
if (methods[i].getName().equals(methodName)) {
JSONArray arr = json.getJSONArray("params");
int length = arr.length();
Object[] args = new Object[length];
for (int i2 = 0; i2 < length; i2++)
args[i2] = arr.get(i2);
methods[i].invoke(this, args);
return;
}
} catch (Exception e) {}
}
}
Run Code Online (Sandbox Code Playgroud)
并使用ClientProcessor:
public class Client extends ClientProcessor {
@Override
public void toasty(String s, boolean bool) {
//make toast here
}
@Override
public void shutdown(int timer) {
//shutdown system within timer
}
public void processJSON(String json) {
process(json);
}
}
Run Code Online (Sandbox Code Playgroud)
JSON由服务器发送到客户端,但可以修改服务器以发送不同的JSON.
我的问题是:
有 100 和 1 种方法可以处理 JSON 消息,以便进行某些处理,但它们都可以归结为:
虽然您可以使用反射调用(从性能角度来说,大多数情况下都可以)来调用方法,但恕我直言,这有点太开放了 - 例如,恶意客户端可能会通过发出调用来使您的系统崩溃wait
。
反射还让您必须正确映射参数,这比您在问题中显示的代码更复杂。
所以不要使用反射。
您可以定义一个简单的interface
,其实现将了解如何处理参数并让您的处理器(更通常称为控制器)调用它,如下所示:
public interface ServiceCall
{
public JsonObject invoke(JsonArray params) throws ServiceCallException;
}
public class ServiceProcessor
{
private static final Map<String, ServiceCall> SERVICE_CALLS = new HashMap<>();
static
{
SERVICE_CALLS.put("toasty", new ToastCall());
}
public String process(String messageStr)
{
try
{
JsonObject message = Json.createReader(new StringReader(messageStr)).readObject();
if (message.containsKey("method"))
{
String method = message.getString("method");
ServiceCall serviceCall = SERVICE_CALLS.get(method);
if (serviceCall != null)
{
return serviceCall.invoke(message.getJsonArray("params")).toString();
}
else
{
return fail("Unknown method: " + method);
}
}
else
{
return fail("Invalid message: no method specified");
}
}
catch (Exception e)
{
return fail(e.message);
}
}
private String fail(String message)
{
return Json.createObjectBuilder()
.add("status", "failed")
.add("message", message)
.build()
.toString();
}
private static class ToastCall implements ServiceCall
{
public JsonObject invoke(JsonArray params) throws ServiceCallException
{
//make toast here
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
149 次 |
最近记录: |