websoket在项目中的使用

项目中要求用户A发起终止申请请求后,对应的相关权限的用户B、用户C等即时收到终止的请求,针对这个需求在项目中加入了websoket功能,下面是具体的使用过程。

1.在maven中添加jar引用

1 <dependency>
2 <groupId>org.springframework</groupId>
3 <artifactId>spring-websocket</artifactId>
4  <version>5.0.9.RELEASE</version>
5 </dependency>

2.在xml的配置,在websocket-context.xml的配置,在service-context.xml的引入

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
    http://www.springframework.org/schema/websocket
    http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd">
<!--
    <aop:aspectj-autoproxy proxy-target-class="true" />
     Enables the Spring MVC @Controller programming model -->

    <bean id="userWebsocket" class="com.gta.scm.websocket.UserWebsocket">
    </bean>

    <bean id="websocket" class="com.gta.scm.websocket.WebsocketEndPoint">
        <property name="list">
            <list>
                <ref bean="userWebsocket" />
            </list>
        </property>
    </bean> 

    <websocket:handlers allowed-origins="*">
        <websocket:mapping path="/websocket.do" handler="websocket"/>
        <websocket:handshake-interceptors>
        <bean class="com.gta.scm.websocket.HandshakeInterceptor">
            <property name="list">
                <list>
                    <ref bean="userWebsocket" />
                </list>
            </property>
        </bean>
        </websocket:handshake-interceptors>
    </websocket:handlers>
</beans>

<import resource="websocket-context.xml"/>

3.在后台拦截器和处理类

会话拦截器

 1 import java.util.List;
 2 import java.util.Map;
 3
 4 import org.springframework.http.server.ServerHttpRequest;
 5 import org.springframework.http.server.ServerHttpResponse;
 6 import org.springframework.stereotype.Component;
 7 import org.springframework.web.socket.WebSocketHandler;
 8 import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
 9
10 import com.gta.scm.websocket.intercept.ServiceHandshakeInterceptor;
11
12
13 @Component
14 public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor{
15     public static final String JSESSIONID = "JSESSIONID";
16     private List<ServiceHandshakeInterceptor> list;
17     /**
18      * 当用户连接ServerSocket时执行
19      * 通过request获取用户登陆的jsessionId的值,放入到集合attributes中
20      */
21     @Override
22     public boolean beforeHandshake(ServerHttpRequest request,
23             ServerHttpResponse response, WebSocketHandler wsHandler,
24             Map<String, Object> attributes) throws Exception {
25
26         if(list!=null){
27             for (ServiceHandshakeInterceptor serviceHandshakeInterceptor : list) {
28                 serviceHandshakeInterceptor.beforeHandshake(request, response, wsHandler, attributes);
29             }
30         }
31         return super.beforeHandshake(request, response, wsHandler, attributes);
32     }
33
34
35
36     /**
37      * 当用户连接完ServerSocket时执行
38      */
39     @Override
40     public void afterHandshake(ServerHttpRequest request,
41             ServerHttpResponse response, WebSocketHandler wsHandler,
42             Exception ex) {
43         if(list!=null){
44             for (ServiceHandshakeInterceptor serviceHandshakeInterceptor : list) {
45                 serviceHandshakeInterceptor.afterHandshake(request, response, wsHandler, ex);
46             }
47         }
48         super.afterHandshake(request, response, wsHandler, ex);
49     }
50
51
52
53     public List<ServiceHandshakeInterceptor> getList() {
54         return list;
55     }
56
57
58
59     public void setList(List<ServiceHandshakeInterceptor> list) {
60         this.list = list;
61     }
62
63 }

 1 import java.util.Map;
 2
 3 import org.springframework.http.server.ServerHttpRequest;
 4 import org.springframework.http.server.ServerHttpResponse;
 5 import org.springframework.web.socket.WebSocketHandler;
 6
 7 public interface ServiceHandshakeInterceptor {
 8     public void beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
 9             Map<String, Object> attributes);
10
11     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
12             Exception ex);
13 }

websokect处理器

 1 import org.springframework.web.socket.CloseStatus;
 2 import org.springframework.web.socket.TextMessage;
 3 import org.springframework.web.socket.WebSocketSession;
 4
 5 public interface ServiceTextWebSocketHandler {
 6     public void handleTextMessage(WebSocketSession session, TextMessage message) ;
 7     public void afterConnectionEstablished(WebSocketSession session);
 8     public void handleTransportError(WebSocketSession session, Throwable exception) ;
 9     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) ;
10
11 }

 1 import java.util.List;
 2
 3 import org.springframework.stereotype.Component;
 4 import org.springframework.web.socket.CloseStatus;
 5 import org.springframework.web.socket.TextMessage;
 6 import org.springframework.web.socket.WebSocketSession;
 7 import org.springframework.web.socket.handler.TextWebSocketHandler;
 8
 9 import com.gta.scm.websocket.intercept.ServiceTextWebSocketHandler;
10 @Component
11 public class WebsocketEndPoint extends TextWebSocketHandler {
12     // 所有连接用户的WebSocketSession,键是用户的jsessionID,值是连接的会话对象
13     private List<ServiceTextWebSocketHandler> list;
14     /**
15      * 该方法在用户前端进行发送消息后进行业务处理的行为
16      */
17     @Override
18     public void handleTextMessage(WebSocketSession session, TextMessage message) {
19
20         if (list!=null) {
21             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) {
22                 serviceTextWebSocketHandler.handleTextMessage(session, message);
23             }
24         }
25     }
26
27     /**
28      * 该方法是连接生效后进行的处理业务行为,每个用户和服务端建立websocket链接时调用
29      */
30     @Override
31     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
32         // 与客户端完成连接后调用
33         if (list!=null) {
34             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) {
35                 serviceTextWebSocketHandler.afterConnectionEstablished(session);
36             }
37         }
38     }
39
40     @Override
41     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
42         // 消息传输出错时调用
43         if (list!=null) {
44             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) {
45                 serviceTextWebSocketHandler.handleTransportError(session,exception);
46             }
47         }
48     }
49
50     @Override
51     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
52         if (list!=null) {
53             for (ServiceTextWebSocketHandler serviceTextWebSocketHandler : list) {
54                 serviceTextWebSocketHandler.afterConnectionClosed(session,closeStatus);
55             }
56         }
57     }
58
59     @Override
60     public boolean supportsPartialMessages() {
61         return false;
62     }
63
64     public List<ServiceTextWebSocketHandler> getList() {
65         return list;
66     }
67
68     public void setList(List<ServiceTextWebSocketHandler> list) {
69         this.list = list;
70     }
71
72
73
74
75 }

  1 import java.io.IOException;
  2 import java.util.HashMap;
  3 import java.util.Iterator;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.Map.Entry;
  7 import java.util.Set;
  8
  9 import javax.servlet.http.Cookie;
 10
 11 import org.apache.commons.lang.StringUtils;
 12 import org.slf4j.Logger;
 13 import org.slf4j.LoggerFactory;
 14 import org.springframework.http.server.ServerHttpRequest;
 15 import org.springframework.http.server.ServerHttpResponse;
 16 import org.springframework.http.server.ServletServerHttpRequest;
 17 import org.springframework.stereotype.Component;
 18 import org.springframework.web.socket.CloseStatus;
 19 import org.springframework.web.socket.TextMessage;
 20 import org.springframework.web.socket.WebSocketHandler;
 21 import org.springframework.web.socket.WebSocketSession;
 22 import org.springframework.web.socket.handler.TextWebSocketHandler;
 23
 24 import com.gta.scm.common.constant.CommonConstant;
 25 import com.gta.scm.common.login.UserLoginRsp;
 26 import com.gta.scm.websocket.intercept.ServiceHandshakeInterceptor;
 27 import com.gta.scm.websocket.intercept.ServiceTextWebSocketHandler;
 28
 29 @Component
 30 public class UserWebsocket  implements ServiceTextWebSocketHandler,ServiceHandshakeInterceptor{
 31     Logger logger = LoggerFactory.getLogger(UserWebsocket.class);
 32     public static final String JSESSIONID = "JSESSIONID";
 33     private static final Map<String,WebSocketSession> users = new HashMap<String,WebSocketSession>();
 34
 35     /**
 36      * 该方法在用户前端进行发送消息后进行业务处理的行为
 37      */
 38     @Override
 39     public void handleTextMessage(WebSocketSession session, TextMessage message) {
 40         logger.debug("handleTextMessage...");
 41          try {
 42             sendMsgToUsers(message.getPayload(), session.getId()) ;
 43         } catch (Exception e) {
 44             e.printStackTrace();
 45         }
 46     }
 47
 48     /**
 49      * 该方法是连接生效后进行的处理业务行为,每个用户和服务端建立websocket链接时调用
 50      */
 51     @Override
 52     public void afterConnectionEstablished(WebSocketSession session) {
 53         logger.debug("afterConnectionEstablished...");
 54         Map<String, Object> m = session.getAttributes();
 55         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 56         users.put(user.getUserInfoId().toString(), session);
 57         logger.debug("put "+user.getUserAccount()+" in sessions");
 58     }
 59
 60     private String getJsessionId(WebSocketSession session){
 61         Object jsessionIdObj = session.getAttributes().get(HandshakeInterceptor.JSESSIONID);
 62         if (jsessionIdObj != null) {
 63             return jsessionIdObj.toString();
 64         }
 65         return null;
 66     }
 67
 68     @Override
 69     public void handleTransportError(WebSocketSession session, Throwable exception) {
 70         logger.debug("handleTransportError...");
 71          if(session.isOpen()){
 72             try {
 73                 session.close();
 74             } catch (IOException e) {
 75                 logger.debug("handleTransportError...",e);
 76             }
 77         }
 78         logger.debug("connection closed......");
 79         Map<String, Object> m = session.getAttributes();
 80         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 81         if(user!=null && users.get(user.getUserInfoId().toString())!=null) {
 82             users.remove(user.getUserInfoId().toString(), session);
 83         }
 84         logger.debug("remove user success......");
 85     }
 86     // 一个客户端连接断开时关闭
 87     @Override
 88     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
 89         logger.debug("afterConnectionClosed...");
 90         Map<String, Object> m = session.getAttributes();
 91         UserLoginRsp user = (UserLoginRsp) m.get(CommonConstant.LOGIN_USER);
 92         if(user!=null && users.get(user.getUserInfoId().toString())!=null) {
 93             users.remove(user.getUserInfoId().toString(), session);
 94         }
 95
 96     }
 97     /**向所有用户发送 信息
 98      * @param message
 99      * @throws Exception
100      */
101     public void sendMsgToAllUsers(String message) throws Exception{
102         logger.debug("sendMsgToAllUsers...");
103         Entry<String,WebSocketSession> entry = null;
104         Iterator<Entry<String,WebSocketSession>> entryIt = users.entrySet().iterator();
105         while(entryIt.hasNext()) {
106             entry = entryIt.next();
107             entry.getValue().sendMessage(new TextMessage(message.getBytes()));
108         }
109     }
110
111     /**向Set<String> jsessionSet 中设置的用户发送信息
112      * @param message
113      * @param jsessionSet
114      * @throws Exception
115      */
116     public void sendMsgToUsers(String message,Set<String> jsessionSet) throws Exception{
117         logger.debug("sendMsgToUsers...");
118         for(String jessionId : jsessionSet) {
119             if (users.containsKey(jessionId)) {
120                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
121
122 //                ShiroAuthorizationHelper.clearAuthenticationInfo(users.get(jessionId).getId());
123             }
124         }
125     }
126     public void sendMsgToUsers(String message,String jessionId) throws Exception{
127         logger.debug("sendMsgToUsers...");
128         if (users.containsKey(jessionId)) {
129                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
130             }
131     }
132     /**
133      * 当用户连接ServerSocket时执行
134      * 通过request获取用户登陆的jsessionId的值,放入到集合attributes中
135      */
136     @Override//
137     public void beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
138             Map<String, Object> attributes) {
139         logger.debug("beforeHandshake...");
140
141                 if (request instanceof ServletServerHttpRequest) {
142                     ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
143                     Cookie cookies[] = servletRequest.getServletRequest().getCookies();
144                     String jsessionId = this.getTicket(cookies);
145                     if (!StringUtils.isNotEmpty(jsessionId)) {
146                         attributes.put(JSESSIONID, this.getTicket(cookies));
147                     }
148                 }
149
150
151     }
152     private String getTicket(Cookie cookies[]){
153         String jsessionId = null;
154         if(cookies != null){
155             for(Cookie ck: cookies){
156                 if(ck.getName().trim().equals(JSESSIONID)){
157                     jsessionId = ck.getValue();
158                     break;
159                 }
160             }
161         }
162         return jsessionId;
163     }
164     /**
165      * 当用户连接完ServerSocket时执行
166      */
167     @Override
168     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
169             Exception ex) {
170
171         logger.debug("afterHandshake...");
172     }
173
174     public void sendMsgToUsers(String message, List<String> idList) throws Exception{
175         logger.debug("sendMsgToUsers...");
176         for(String jessionId : idList) {
177             if (users.containsKey(jessionId)) {
178                 logger.debug("sendMsgToUsers..."+jessionId);
179                 users.get(jessionId).sendMessage(new TextMessage(message.getBytes()));
180
181             }
182         }
183
184     }
185 }

4.在具体业务的地方调用

1     //向学生端发通知强制退出到首页
2             List<String> userList=sysMessageBaseService.getTrainingUser(usp.getTrainingId());
3             String[] idStr = (String[])userList.toArray(new String[userList.size()]);
4             Set<String> set = new HashSet<String>(Arrays.asList(idStr));
5             userWebsocket.sendMsgToUsers("signOut", set);

 1 String[] idStr = new String[userAccount.size()];
 2         String[] ownId = new String[userAccount.size()];
 3         for (int i = 0; i < userAccount.size(); i++) {
 4             String str = GsonUtils.parseJson(userAccount.get(i));
 5             JSONObject object = JSONObject.fromObject(str);
 6             if (object.getString("organizationCode").equals(partyCode))// 自己方人员
 7             {
 8                 ownId[i] = object.getString("userId");
 9             } else {
10                 idStr[i] = object.getString("userId");
11             }
12
13         }
14         String strMessage = "";
15         String myMessage = "1";
16         if (stateType == CommonEnum.TradingContractStatus.SEND_TERMINATION.getTypeCode()) // 发送终止
17         {
18             strMessage="apply;"+contractCode;
19             //strMessage = "对方申请终止" + contractCode + "(合同号),请尽快处理!";
20         } else if (stateType == CommonEnum.TradingContractStatus.CONFIRMED.getTypeCode())// 终止不同意
21         {
22             strMessage="disagree;"+contractCode;
23             //strMessage = "对方不同意终止" + contractCode + "(合同号),请尽快处理!";
24         } else if (stateType == CommonEnum.TradingContractStatus.TERMINATION.getTypeCode())// 终止不同意
25         {
26             strMessage="agree;"+contractCode;
27             //strMessage = "对方同意终止" + contractCode + "(合同号),请尽快处理!";
28         } else if (stateType == 5)// 终止取消
29         {
30             strMessage="cancel;"+contractCode;
31             //strMessage = "对方取消终止" + contractCode + "(合同号),请尽快处理!";
32         }
33         infoAndOut(idStr, strMessage); // 对方操作
34         infoAndOut(ownId, myMessage); // 我方刷新数据

5.websoket.js的引入与在具体页面的实现

 1 /**
 2  *
 3  * @param $
 4  */
 5 (function($) {//每页开始直接复制
 6     $.websocket = {//外部可以直接访问的对象, 要导入该文件 调用对象$.devfrw.base.demo
 7         connect : function(urlPath,initOpt) {//外部可以直接访问的对象的方法, 要导入该文件 调用方法$.devfrw.base.demo.pub
 8                 setUrl(urlPath);
 9                 var opt={onopen:function(){},onmessage:function(event){},onclose:function(event){}};
10                 if(initOpt){
11                     opt= $.extend(opt, initOpt);
12                 };
13                 if (!url) {
14                     alert(‘websocket url 未设置!‘);
15                     return;
16                 }
17                 ws =new WebSocket(url);
18                 ws.onopen = function () {
19                 //    console.log(‘打开链接‘);
20                     opt.onopen();
21                 };
22                 ws.onmessage = function (event) {
23                 //    console.log(‘消息接收‘);
24                     opt.onmessage(event);
25                 };
26                 ws.onclose = function (event) {
27                 //    console.log(‘关闭链接‘);
28                     opt.onclose(event);
29                 };
30         },
31         setUrl:function(urlPath){
32             setUrl(urlPath);
33         },
34         send:function(message){
35               if (ws != null) {
36                     ws.send(message);
37                 } else {
38                     alert(‘websocket链接不存在!‘);
39                 }
40         },
41         disconnect:function(){
42             if (ws != null) {
43                 ws.close();
44                 ws = null;
45             }
46         }
47     };
48     var ws = null;
49     var url = null;
50     function setUrl(urlPath) {
51           if (window.location.protocol == ‘http:‘) {
52               url = ‘ws://‘ + window.location.host + urlPath;
53           } else {
54               url = ‘wss://‘ + window.location.host + urlPath;
55           }
56     }
57 })(jQuery);//直接复制 一定要;号

 1 $.websocket.connect(‘/portal/websocket.do‘, {
 2         onmessage : function(event) {//接收数据
 3             if(event.data!=""&&event.data!=null)
 4             {
 5             if (contains(event.data, "clear")) {
 6                 $(".pay").each(function() {
 7                     var id = $(this).parent().attr("id");
 8                     var salescode = $(this).parent().attr("salescode");
 9                     if (contains(event.data, id + ";")) {
10                         $("#send" + id).removeClass("disabled");
11                         $("#send" + id).addClass("send");
12                         $("#pay" + id).removeClass("pay");
13                         $("#pay" + id).addClass("disabled");
14                         $("#delete" + id).removeClass("disabled");
15                         $("#delete" + id).attr("onclick","del("+salescode+")");
16                     }
17                 });
18             }
19             if (contains(event.data, "signOut")) {
20                  layer.msg("轮次结束请返回首页!", {
21                         time: 5000,
22                         shade: 0.6,
23                         success: function (layero, index) {
24                             var msg = layero.text();
25                             var i = 5;
26                             var timer = null;
27                             var fn = function () {
28                                 layero.find(".layui-layer-content").text(msg + ‘(倒计时‘ + i + ‘秒)‘);
29                                 if (!i) {
30                                     layer.close(index);
31                                     clearInterval(timer);
32                                 }
33                                 i--;
34                             };
35                             timer = setInterval(fn, 1000);
36                             fn();
37                         },
38                     }, function () {
39                         window.location.href="${basePath}student/main/index";
40                     });
41
42             }
43             }
44
45         },
46         onclose : function(event) {
47                 $.websocket.disconnect();
48         }
49     });

原文地址:https://www.cnblogs.com/songStar/p/11022501.html

时间: 2024-11-09 00:55:32

websoket在项目中的使用的相关文章

用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中

我最近在用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中,第一次写项目,写过这类项目的多多提意见,哪方面的意见都行,有代码或者demo的求赏给我,谢谢

DotNet项目中的一些常用验证操作

在项目中需要对用户输入的信息,以及一些方法生成的结果进行验证,一般在项目中较多的采用js插件或js来进行有关信息的校验,但是从项目安全性的角度进行考虑,可对系统进行js注入. 如果在后台对用户输入的信息进行验证会相对的安全,在出现信息验证不合法时,可以直接在程序中抛出异常,终止程序的运行. 现在提供几种较为常用的验证方法,可以减少在项目中开发时间和错误性: 1.判断域名:         /// <summary>         /// 普通的域名         /// </summ

javaWeb项目中如何实现在线查看pdf文件

最近有需求要实现在网页直接查看pdf,word,excel文件.但是实际当中并没有很好的开源插件供我们使用,确实有一些付费的插件不错,也很好用,但是对于我来说都不适合. 现在只是单纯的找到了围魏救赵的方法. 就是先实现显示pdf文件,其他文件用别的方式去转成pdf.虽然这个方法确实不好,但是也是没有办法的办法了,如果以后能有更好的,那就再发布别的吧. 这里我就直接介绍pdf的显示方法. 直接上干货. 首先在E:\tomcat8\webapps这个目录下面拷贝下面这个文件 http://yunpa

Python+Selenium进行UI自动化测试项目中,常用的小技巧2:读取配置文件(configparser,.ini文件)

在自动化测试项目中,可能会碰到一些经常使用的但 很少变化的配置信息,下面就来介绍使用configparser来读取配置信息config.ini 读取的信息(config.ini)如下: [config]platformName=AndroidappPackage=com.sheinsideappActivity=.module.GuideActivitybaseUrl=http://0.0.0.0:4723/wd/hubfindElementTimes=10[cmd]openAppium=nod

团队项目中个人的定位及计划

我们团队在这一次的移动APP开发计划中准备做一个针对上海地区大学分数线进行专业推荐的APP,根据前几章的学习,团队中的成员将会被初步分为开发人员.测试人员以及PM(program manager).我在这次的软件开发中担任开发人员的职务. 在开发开始的阶段,全员首先一起明确这次APP的主题,一起分析好这款APP将要实现怎样的功能,将要面向哪些受众:对于市面上的同类软件,我们还能添加哪些实用的功能.首先将会尽可能地将上海地区内高校近几年的分数线.每个系的最低录取分数统计好录入系统中,再根据考生相应

160504项目中的error

在学习时,曾经遇到将同组的项目导入时出现红叉的情况.但是没有发现具体错误.开始以为是build path 的问题,于是在Libraries中将相关Jar包重新检查并添加了一遍,但并没有解决问题.后来仔细检查后才发现,是一个很简单的问题,之前都想复杂了.JDK版本不一样,把JDK7换掉重新装JDK8,再把相关配置好,红叉就解决大半. 作为菜鸟程序员,有时候一个很小的问题就能造成很大影响.而经验不足时,更不知道从何入手.为了能顺利编写项目,更为了能在编写项目时能解决出现的问题和错误而不是不知所措,就

准备在新项目中使用pgsql

pgsql大象数据库 是我最近在关注的一款开源数据库,可以自由修改,没那么多限制,准备在新项目中使用 http://blog.163.com/[email protected]/blog/static/16387704020141229159715/

Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图

标签: Android百度地图API Key  分类: Android 百度地图开发(2)  最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地图入手,其实他们的用法都差不多,本篇文章就带领大家在自己的Android项目中加入百度地图的功能,接下来我会写一系列关于百度地图的文章,欢迎大家到时候关注!   一 申请API key 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/a

设置tableview的滚动范围--iOS开发系列---项目中成长的知识三

设置tableview的滚动范围 有时候tableview的footerview上的内容需要向上拖动界面一定距离才能够看见, 项目中因为我需要在footerviw上添加一个按钮,而这个按钮又因为这个原因点不中,所以找到了解决办法! 添加如下方法即可 -(void)scrollViewDidScroll:(UIScrollView *)scrollView { self.tableView.contentSize = CGSizeMake(0,MZT_SCREEN_HEIGHT); }