SpringMVC+WebSocket的通用接口映射实现

来源:互联网 发布:高通900e端口转9008 编辑:程序博客网 时间:2024/05/23 19:15

首先准备环境:SpringMVC4.0、WebSocket、Tomcat7.0,具体配置就不说了,网上有。

目的:在控制层(Controller)实现springmvc和websocket的统一接口映射,即websocket访问后台也可以像springmvc访问Controller方法一样

实现原理:定义一个主要的websocket处理类,在这个websocket的基础下进行接口分发和参数映射。


具体方法:

1.通过字符串或JSON(方便映射前端的js对象)来传递访问的路径,也就是调用Controller的某个方法。RequestMappingHandlerMapping对象持有Controller的所有配置接口和方法信息,遍历接口信息,匹配到前端的访问路径就可以进行调用了。

2.参数映射有很多方案,最简单的统一用Map传参,Controller的接口也支持,这样就实现了接口的通用。


下面是主要的websocket消息处理类

@SuppressWarnings("unchecked")public class MainHandler extends TextWebSocketHandler{@Autowired  private RequestMappingHandlerMapping requestMappingHandlerMapping; @Overridepublic void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {// TODO Auto-generated method stubString msg = message.getPayload();Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping.getHandlerMethods();Object result = null;String url = msg;Map<String, Object> parameter = new HashMap<String, Object>();Pattern pattern = Pattern.compile("^\\{(\"\\w+\":\\S+,{0,1})+\\}$");if(pattern.matcher(msg).matches()){JSONObject json = JSONObject.fromObject(message.getPayload());if(json.get("url") != null){url = String.valueOf(json.get("url"));if(json.get("params") != null){parameter = (Map<String, Object>) json.get("params");}}}for (Map.Entry<RequestMappingInfo, HandlerMethod> m : map.entrySet()) {RequestMappingInfo info = m.getKey();              HandlerMethod method = m.getValue();             PatternsRequestCondition p = info.getPatternsCondition();             if(p.getPatterns().size() > 0 && p.getPatterns().toArray()[0].equals(url)){            String url_pt = String.valueOf(p.getPatterns().toArray()[0]);            String methodName = url_pt.substring(url_pt.lastIndexOf('/')+1);            Class<?> cls = method.getMethod().getDeclaringClass();            Object controller = cls.newInstance();            boolean success = true;            try{            result = cls.getDeclaredMethod(methodName, Map.class).invoke(controller, parameter);            }catch(Exception e){            success = false;            }            if(!success){            try{                result = cls.getDeclaredMethod(methodName).invoke(controller);                }catch(Exception e){                success = false;                }                     }            if(!success)result = "未找到指定方法或方法参数不匹配";            break;            }              }if(result != null){session.sendMessage(new TextMessage(String.valueOf(result).getBytes()));}}}

前端发送:

WSClient.fn.pushMsgEvent = function(msgEvent){if(typeof msgEvent == "function")this.msgPool.push(_opts.msgEvent);return this.msgPool;}



细节说明:
1.一般来说,SpringMVC和WebSocket的接口整合是在service层,SpringMVC的Controller层通常不做任何业务处理或少量处理,只负责提供接口。个人实现这套方案只是想通过注解的形式来定义WebSocket的接口,顺便通用一下
2.如果Controller的接口参数不想用Map,则可以重载一个参数为Map的函数,如下:

@RequestMapping("/test")public @ResponseBody List test(HttpServletRequest request){return test(request.getParameterMap());}public @ResponseBody List test(Map map){System.out.println(map);List<String> tmp = new ArrayList<String>();tmp.add("1222");tmp.add("2333");return tmp;}


3.后续补充...

0 0
原创粉丝点击