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

首先准备环境: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; 
	
	
	@Override
	public void handleTextMessage(WebSocketSession session,
			TextMessage message) throws Exception {
		// TODO Auto-generated method stub
		String 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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值