最近整理了一些開發中常用的技術,分享一下個人的心得,如有不對之處,歡迎指出。
目錄
3.jeesite框架Apache Commons Email的使用
6.JackJson的objectMapper的json對象化
1.shiro權限控制在項目中的使用
1.jsp頁面導入shiro標籤庫
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
標籤庫定義在shiro-web.jar包下的META-INF/shiro.tld中定義。
2.常用shiro標籤
hasRole標籤
<shiro:hasRole name="admin">
<span> 擁有角色admin</span>
</shiro:hasRole>
如果當前Subject有角色將顯示span內容。
hasAnyRoles標籤
<shiro:hasAnyRoles name="admin,user">
<span>擁有角色admin</span>
</shiro:hasAnyRoles>
如果當前Subject有任意一個角色(或的關係)將顯示span內容。
lacksRole標籤
<shiro:lacksRole name="abc">
<span>沒有有角色abc</span>
</shiro:lacksRole>
如果當前Subject沒有角色abc將顯示span內容。
hasPermission標籤
<shiro:hasPermission name="user:create">
<span>擁有權限user:create</span>
</shiro:hasPermission>
如果當前Subject有權限將顯示span內容。
lacksPermission標籤
<shiro:lacksPermission name="org:create">
<span>沒有有權限user:create</span>
</shiro:lacksPermission>
如果當前Subject沒有權限將顯示span內容。
在java後臺代碼中如何通過shrio根據用戶的角色不同對數據進行過濾,需要結合shiro的subject對象和實體類中sqlMap進行sql語句的拼接來達到數據的過濾
Java代碼
xml中sql拼接
注意:在原來的jeesite框架中每個實體類都繼承了BaseEntity基類,而基類中已經加入了Map類型的sqlMap,所以每個繼承了BaseEntity類都可以直接調用 getSqlMap方法若沒有需自己重寫
@JsonIgnore
@XmlTransient
public Map<String, String> getSqlMap() {
if (sqlMap == null){
sqlMap = Maps.newHashMap();
}
return sqlMap;
}
public void setSqlMap(Map<String, String> sqlMap) {
this.sqlMap = sqlMap;
}
2.java反射技術比較實體類字段的不同
Java代碼:
1.存放不同信息的類
public class ChangeInfo extends DataEntity<ChangeInfo> {
private static final long serialVersionUID = 1L;
private String title; // 改變標題 (變量名)
private String name; // 變更項的名稱 (中文名)
private String type; // 變更顯示類型(1:顯示content內容 2: 顯示前後(oldInfo,newInfo)變更信息)
private String content; // 提示內容
private String oldInfo; // 之前內容
private String newInfo; // 之後內容
}
2.設置需要比較的對象的字段名稱
public List<ChangeInfo>compareDetails(Object obj){
//存放新舊對象改變的內容
List<ChangeInfo> list = new ArrayList<ChangeInfo>();
//新的對象
Object newVersion = obj;
//舊的對象
Object oldVersion = XXXService.get(newVersion.getLastVersionId());
//需要比較的字段
String[]opDiffNameArray={"XX編碼","XX名稱","XX要求","XX目的","XX範圍","XX使用前","XX使用過程中","XX使用過程後","XX注意事項"};
//對應的類中的成員變量
String[]opDiffArray={"code","name","requirement","purpose","range","beforeUse","inUse","afterUse","notice"};
contrastObj(newVersion, oldVersion, opDiffArray, opDiffNameArray, list);
return list;
}
3.利用反射技術比較實體類的字段值
public void contrastObj(Object pojo1, Object pojo2, String[] diffMemberArray, String[] diffMemberName, List<ChangeInfo> diffList) {
Map<String, Object> diffMap = new HashMap<String, Object>();
//map存儲中英文對應
for (int i = 0; i < diffMemberArray.length; i++) {
diffMap.put(diffMemberArray[i], diffMemberName[i]);
}
//英文List
List<String> diffMember = Arrays.asList(diffMemberArray);
try {
Class clazz = pojo1.getClass();
//獲取obj1的所有字段
Field[] fields = pojo1.getClass().getDeclaredFields();
//遍歷obj1所有字段
for (Field field : fields) {
//如果該字段不再Map中遍歷下一個字段
if (!diffMember.contains(field.getName())) {
continue;
}
//利用反射獲取對應字段的get,set方法
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz); //獲取get方法
Method getMethod = pd.getReadMethod();
Object o1 = null;
Object o2 = null;
if (pojo1 != null) {
//調用obj1的對應字段的get方法
o1 = getMethod.invoke(pojo1);
}
if (pojo2 != null) {
//調用obj2的對應字段的get方法
o2 = getMethod.invoke(pojo2);
}
String str1 = "";
String str2 = "";
//如果對象是日期類型格式化
if (o1 instanceof Date) {
str1 = new SimpleDateFormat("yyyy-MM-dd").format(o1);
str2 = new SimpleDateFormat("yyyy-MM-dd").format(o2);
} else if (o1 instanceof String) {
str1 = (String) o1;
str2 = (String) o2;
} else {
continue;
}
//判斷返回的對象不相等
if ((str1 != null && !str1.equals(str2)) || (str2 != null && !str2.equals(str1))) {
ChangeInfo change = new ChangeInfo();
//字段英文名稱
change.setTitle(field.getName());
//中文名稱
change.setName((String) diffMap.get(field.getName()));
//舊信息
change.setOldInfo(str2);
//新信息
change.setNewInfo(str1);
diffList.add(change);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
3.jeesite框架Apache Commons Email的使用
1.導入相關依賴
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.2</version>
</dependency>
2.創建.ftl文件
<html>
<head>
<meta http-equiv="content-type" content="text/html;chartset=utf-8" ;>
</head>
<body>
<h1>${subject}</h1>
<p>${content}</p>
</body>
</html>
3.註冊個人郵箱開啓pop3/smpt服務(以新浪郵箱舉列)
4.修改sendMailUtils類
① 配置郵箱地址
private static MailLogDao mailLogDao=SpringContextHolder.getBean(MailLogDao.class);
// private static final String smtphost = "192.168.1.70";
private static final String from = "[email protected]";
private static final String fromName = "XXX";
private static final String charSet = "utf-8";
private static final String username = "[email protected]";
private static final String password = "xxxx";
② 配置smtp地址
static {
// 126
hostMap.put("smtp.126", "smtp.126.com");
// qq
hostMap.put("smtp.qq", "smtp.qq.com");
// 163
hostMap.put("smtp.163", "smtp.163.com");
// sina
hostMap.put("smtp.sina", "smtp.sina.com.cn");
}
③ 根據郵箱號獲取smtp地址
public static String getHost(String email) throws Exception {
Pattern pattern = Pattern.compile("\\w+@(\\w+)(\\.\\w+){1,2}");
Matcher matcher = pattern.matcher(email);
String key = "unSupportEmail";
if (matcher.find()) {
key = "smtp." + matcher.group(1);
}
if (hostMap.containsKey(key)) {
return hostMap.get(key);
} else {
throw new Exception("unSupportEmail");
}
}
④ 根據郵箱號獲取smtp端口號
public static int getSmtpPort(String email) throws Exception {
Pattern pattern = Pattern.compile("\\w+@(\\w+)(\\.\\w+){1,2}");
Matcher matcher = pattern.matcher(email);
String key = "unSupportEmail";
if (matcher.find()) {
key = "smtp.port." + matcher.group(1);
}
if (hostMap.containsKey(key)) {
return Integer.parseInt(hostMap.get(key));
} else {
return 25;
}
}
⑤ 填寫郵箱內容
public static void sendEmail(Tenant tenant)throws MessagingException {
String subject="註冊通知!";
String content="您好"+"</br>"+"歡迎註冊XX"+"</br>;
Map<String, Object> map = new HashMap<String, Object>();
map.put("subject", subject);
map.put("content", content);
String templatePath = "mailtemplate/test.ftl";
sendFtlMail(tenant.getEmail(), subject, templatePath, map);
}
⑥ 調用郵箱發送方法
/**
* 發送模板郵件
*
* @param toMailAddr 收信人地址
* @param subject email主題
* @param templatePath 模板地址
* @param map 模板map
*/
public static void sendFtlMail(String toMailAddr, String subject,
String templatePath, Map<String, Object> map) {
Template template = null;
Configuration freeMarkerConfig = null;
HtmlEmail hemail = new HtmlEmail();
try {
hemail.setHostName(getHost(from));
hemail.setSmtpPort(getSmtpPort(from));
hemail.setCharset(charSet);
hemail.addTo(toMailAddr);
hemail.setFrom(from, fromName);
hemail.setAuthentication(username, password);
hemail.setSubject(subject);
hemail.setSSL(Boolean.TRUE); // 設定是否使用SSL email.setSslSmtpPort("465")
freeMarkerConfig = new Configuration();
freeMarkerConfig.setDirectoryForTemplateLoading(new File(
getFilePath()));
// 獲取模板
template = freeMarkerConfig.getTemplate(getFileName(templatePath),
new Locale("Zh_cn"), "UTF-8");
// 模板內容轉換爲string
String htmlText = FreeMarkerTemplateUtils
.processTemplateIntoString(template, map);
System.out.println(htmlText);
hemail.setMsg(htmlText);
hemail.send();
System.out.println("email send true!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("email send error!");
}
}
4.jeesite框架excel表的導入導出
- 導入pom.xml依賴
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${poi.version}</version>
</dependency>
2.實體類添加ExcelFiled註解
注:只有添加@ExcelField註解才能在導入導出的時候將字段映射
- 導出Excel表數據
- 下載Excel模板
5 導入excel表數據
5.json對象和字符串的相互轉換
5.1 jsp頁面中json對象和字符串的轉換
使用json中的parser方法轉換;
var str='{"name":"fendouer", "age":23}'; //這是一個json字符串''
var ob=JSON.parse(str) ; //返回一個新對象
console.log(ob.name)
把json中的stringify對象轉換成字符串
var obj={"student":[{"name":"cyl","age":"21"},{"name":"hyj","age":"23"}]}; //這是一個json對象
var str=obj.student[0].name;
var newstr=JSON.stringify(str); //返回一個新字符串
console.log(newstr);
在Firefox,chrome,opera,safari,ie9,ie8等高級瀏覽器直接可以用JSON對象的stringify()和parse()方法。
JSON.stringify(obj) 將JSON對象轉爲字符串。
JSON.parse(string) 將字符串轉爲JSON對象格式。
擴展 :jquery插件支持的轉換方式:
jQuery 3.0開始,$.parseJSON已經過時(不建議使用)。要將字符串解析成JSON對象,請使用原生的JSON.parse方法來代替。
5.2 java代碼中json對象和字符串的轉換
/** * json字符串轉化爲對象 */
String jsonString ="{name:'Antony',age:'12',sex:'male',telephone:'88888'}";
Staff staff = JSON.parseObject(jsonString, Staff.class); System.out.println(staff.toString());
/** * 對象轉化爲json字符串 */
String jsonStr = JSON.toJSONString(staff);
System.out.println(jsonStr);
6.JackJson的objectMapper的json對象化
Java下常見的Json類庫有Gson、JSON-lib和Jackson等,Jackson相對來說比較高效,在項目中主要使用Jackson進行JSON和Java對象轉換,下面給出一些Jackson的JSON操作方法。
1、準備工作
Jackson有1.x系列和2.x系列,2.x系列有3個jar包需要下載:
jackson-core-2.2.3.jar(核心jar包)
jackson-annotations-2.2.3.jar(該包提供Json註解支持)
jackson-databind-2.2.3.jar
一個maven依賴就夠了
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
JSON序列化和反序列化使用的User類
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. java對象轉json字符串
/**
* ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中實現。
* ObjectMapper有多個JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介質中。
* writeValue(File arg0, Object arg1)把arg1轉成json序列,並保存到arg0文件中。
* writeValue(OutputStream arg0, Object arg1)把arg1轉成json序列,並保存到arg0輸出流中。
* writeValueAsBytes(Object arg0)把arg0轉成json序列,並把結果輸出成字節數組。
* writeValueAsString(Object arg0)把arg0轉成json序列,並把結果輸出成字符串。
*/
User user = new User();
user.setName("zhangsan");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
System.out.println(json);
//輸出結果:{"name":"zhangsan"}
3.JSON字符串轉java對象
String json = "{\"name\":\"zhangsan\"}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
4.json註解
Jackson提供了一系列註解,方便對JSON序列化和反序列化進行控制,下面介紹一些常用的註解。
@JsonIgnore 此註解用於屬性上,作用是進行JSON操作時忽略該屬性。
@JsonFormat 此註解用於屬性上,作用是把Date類型直接轉化爲想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。
@JsonProperty 此註解用於屬性上,作用是把該屬性的名稱序列化爲另外一個名稱,如把trueName屬性序列化爲name, @JsonProperty("name")。
7.Websocket的基本使用
1.pom.xml文件添加依賴jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
2.服務註冊
**
* 註解配置模式
* Created by 86557 on 2017/4/19.
*/
@Configuration
@EnableWebSocket
@EnableWebMvc
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
// 用來註冊WebSocket Server實現類,第二個參數是訪問WebSocket的地址
webSocketHandlerRegistry.addHandler(new AnalysisWebSocketHandler(), "/myHandler").addInterceptors(new HandshakeInterceptor());
webSocketHandlerRegistry.addHandler(new AnalysisWebSocketHandler(), "/sockjs/myHandler").addInterceptors(new HandshakeInterceptor()).withSockJS();
}
}
注:前端會發起一個webSocket連接請求,而webSockeConfig會接收到這個請求,接收請求之後webSocketConfig類創建兩個類的對象一個是HandshakeInterceptor類,一個是AnalysisWebSocketHandler類,HandshakeInterceptor類用於webSocket建立連接之前的握手,
AnalysisWebSocketHandler類用於處理webSocket連接之後的業務邏輯處理。
3.握手
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
*
* @param request
* @param response
* @param wsHandler
* @param attributes
* @return
* @throws Exception
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse
response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws
Exception {
if (getSession(request) != null) {
ServletServerHttpRequest servletRequest =
(ServletServerHttpRequest) request;
HttpServletRequest httpServletRequest =
servletRequest.getServletRequest();
Subject subject = SecurityUtils.getSubject();
SystemAuthorizingRealm.Principal principal =
(SystemAuthorizingRealm.Principal) subject.getPrincipal();
if (principal == null) {
//沒有獲取登陸用戶信息,握手失敗
return false;
}
attributes.put("userId", principal.getId());
}
return super.beforeHandshake(request, response, wsHandler,
attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse
response, WebSocketHandler wsHandler, Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
private HttpSession getSession(ServerHttpRequest request) {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverRequest =
(ServletServerHttpRequest) request;
return serverRequest.getServletRequest().getSession(false);
}
return null;
}
}
注 WebSocket握手攔截器用來攔截和處理客戶端和服務器端分別在握手前和握手後的事件,我們這裏添加這個攔截器是爲了清晰的知道什麼時候以及是否握手成功。
4.webscoket處理類
@Service
public class AnalysisWebSocketHandler extends TextWebSocketHandler {
private static final Map<String, List<WebSocketSession>> users;
private static SystemService systemService = SpringContextHolder.getBean(SystemService.class);
private static NotifyDao notifyDao=SpringContextHolder.getBean(NotifyDao.class);
static {
users=new HashMap<>();
}
// 在afterConnectionEstablished連接建立成功之後,記錄用戶的連接標識,便於後面發信息,這裏我是記錄將id記錄在Map集合中。
@Override
public void afterConnectionEstablished(WebSocketSession session) throws
Exception {
super.afterConnectionEstablished(session);
String userId = MapUtils.getString(session.getAttributes(),
"userId");
//記錄連接的session
if(users.containsKey(userId)) {
users.get(userId).add(session);
}else{
List<WebSocketSession>socketSessionList=Lists.newArrayList();
socketSessionList.add(session);
users.put(userId, socketSessionList);
}
}
/**
* 前臺js調用ws.send(requestData)函數會觸發此函數,一般業務邏輯在此處理
* @param session
* @param message
* @throws Exception
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage
message) throws Exception {
try {
session.sendMessage(new TextMessage( JSON.toJSONString(searchNotify(session))));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable
exception) throws Exception {
super.handleTransportError(session, exception);
System.out.println("handleTransportError");
String userId = MapUtils.getString(session.getAttributes(),
"userId");
users.get(userId).remove(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus
status) throws Exception {
super.afterConnectionClosed(session, status);
System.out.println("afterConnectionClosed");
String userId = MapUtils.getString(session.getAttributes(),
"userId");
users.get(userId).remove(session);
}
}
注: 這個類處理來之瀏覽器(客戶端)的WebSocket請求。在這個例子中,我們創建一個叫AnalysisWebSocketHandler的類,並讓它繼承TextWebsocketHandler類。然後重寫父類方法handlerTextMessage(),每當客戶端發送信息過來,都會由這個函數接收並處理。這個函數會把服務端處理的數據返回給客戶端。
5.前端websocket客戶端配置
function connectWS() {
var url = 'ws://' + window.location.host + "${pageContext.request.contextPath}/myHandler";
if (!url) {
alert('Select whether to use W3C WebSocket or SockJS');
return;
}
if (url.indexOf("sockjs") != -1) {
ws = new SockJS(url);
} else {
if ('WebSocket' in window) {
ws = new WebSocket(url);//ws://localhost:8080/myHandler
} else {
ws = new SockJS(url);
}
}
ws.onopen = function () {
console.log("websocket已打開");
sendMsg();
};
ws.onmessage = function (event) {
console.log("websocket 收到消息:");
var responseData = $.parseJSON(event.data);
if (responseData.resultStatus == '1') {
if (responseData.count.length > 5) {
alert('未登錄或登錄超時。請重新登錄,謝謝!');
top.location = "${ctx}";
} else if (responseData.count != '0') {
if ($("#notifyLi:hidden").length != 0) {
$("#notifyLi").show();
}
$("#unReadNotifys").html(responseData.count);
} else {
$("#notifyLi").hide();
}
} else if (responseData.resultStatus == '0') {
alert(responseData.message);
window.location.reload(true);
} else {
window.location.reload(true);
}
};
ws.onclose = function (event) {
console.log("websocket 關閉");
};
ws.onerror = function (event) {
console.log("websocket出錯");
};
}
6.webSocket的應用背景
決定手頭的工作是否需要使用WebSocket技術的方法很簡單:
- 你的應用提供多個用戶相互交流嗎?
- 你的應用是展示服務器端經常變動的數據嗎?
如果你的回答是肯定的,那麼請考慮使用WebSocket。如果你仍然不確定,並想要更多的靈感,這有一些殺手鐗的案例。
①社交訂閱
對社交類的應用的一個裨益之處就是能夠即時的知道你的朋友正在做什麼。雖然聽起來有點可怕,但是我們都喜歡這樣做。你不會想要在數分鐘之後才能知道一個家庭成員在餡餅製作大賽獲勝或者一個朋友訂婚的消息。你是在線的,所以你的訂閱的更新應該是實時的。
②多玩家遊戲
網絡正在迅速轉變爲遊戲平臺。在不使用插件(我指的是Flash)的情況下,網絡開發者現在可以在瀏覽器中實現和體驗高性能的遊戲。無論你是在處理DOM元素、CSS動畫,HTML5的canvas或者嘗試使用WebGL,玩家之間的互動效率是至關重要的。我不想在我扣動扳機之後,我的對手卻已經移動位置。
③協同編輯/編程
我們生活在分佈式開發團隊的時代。平時使用一個文檔的副本就滿足工作需求了,但是你最終需要有一個方式來合併所有的編輯副本。版本控制系統,比如Git能夠幫助處理某些文件,但是當Git發現一個它不能解決的衝突時,你仍然需要去跟蹤人們的修改歷史。通過一個協同解決方案,比如WebSocket,我們能夠工作在同一個文檔,從而省去所有的合併版本。這樣會很容易看出誰在編輯什麼或者你在和誰同時在修改文檔的同一部分。
④點擊流數據
分析用戶與你網站的互動是提升你的網站的關鍵。HTTP的開銷讓我們只能優先考慮和收集最重要的數據部分。然後,經過六個月的線下分析,我們意識到我們應該收集一個不同的判斷標準——一個看起來不是那麼重要但是現在卻影響了一個關鍵的決定。與HTTP請求的開銷方式相比,使用Websocket,你可以由客戶端發送不受限制的數據。想要在除頁面加載之外跟蹤鼠標的移動?只需要通過WebSocket連接發送這些數據到服務器,並存儲在你喜歡的NoSQL數據庫中就可以了(MongoDB是適合記錄這樣的事件的)。現在你可以通過回放用戶在頁面的動作來清楚的知道發生了什麼。
⑤股票基金報價
金融界瞬息萬變——幾乎是每毫秒都在變化。我們人類的大腦不能持續以那樣的速度處理那麼多的數據,所以我們寫了一些算法來幫我們處理這些事情。雖然你不一定是在處理高頻的交易,但是,過時的信息也只能導致損失。當你有一個顯示盤來跟蹤你感興趣的公司時,你肯定想要隨時知道他們的價值,而不是10秒前的數據。使用WebSocket可以流式更新這些數據變化而不需要等待。
⑥體育實況更新
現在我們開始討論一個讓人們激情澎湃的愚蠢的東西——體育。我不是運動愛好者,但是我知道運動迷們想要什麼。當愛國者在打比賽的時候,我的妹夫將會沉浸於這場比賽中而不能自拔。那是一種瘋狂癡迷的狀態,完全發自內心的。我雖然不理解這個,但是我敬佩他們與運動之間的這種強烈的聯繫,所以,最後我能做的就是給他的體驗中降低延遲。如果你在你的網站應用中包含了體育新聞,WebSocket能夠助力你的用戶獲得實時的更新。
⑦多媒體聊天
視頻會議並不能代替和真人相見,但當你不能在同一個屋子裏見到你談話的對象時,視頻會議是個不錯的選擇。儘管視頻會議私有化做的“不錯”,但其使用還是很繁瑣。我可是開放式網絡的粉絲,所以用WebSockets getUserMedia API和HTML5音視頻元素明顯是個不錯的選擇。WebRTC的出現順理成章的成爲我剛纔概括的組合體,它看起來很有希望,但其缺乏目前瀏覽器的支持,所以就取消了它成爲候選人的資格。
⑧基於位置的應用
越來越多的開發者借用移動設備的GPS功能來實現他們基於位置的網絡應用。如果你一直記錄用戶的位置(比如運行應用來記錄運動軌跡),你可以收集到更加細緻化的數據。如果你想實時的更新網絡數據儀表盤(可以說是一個監視運動員的教練),HTTP協議顯得有些笨拙。借用WebSocket TCP鏈接可以讓數據飛起來。
⑨在線教育
上學花費越來越貴了,但互聯網變得更快和更便宜。在線教育是學習的不錯方式,尤其是你可以和老師以及其他同學一起交流。很自然,WebSockets是個不錯的選擇,可以多媒體聊天、文字聊天以及其它優勢如與別人合作一起在公共數字黑板上畫畫。
8.webService的基本使用
W3C組織對其的定義如下,它是一個軟件系統,爲了支持跨網絡的機器間相互操作交互而設計。Web Service服務通常被定義爲一組模塊化的API,它們可以通過網絡進行調用,來執行遠程系統的請求服務。簡單的說:WebService即Web服務,它是一種跨編程語言和跨操作系統平臺的遠程調用技術。
Web服務:基於HTTP和XML的技術,HTTP是互聯網上應用最爲廣泛的一種網絡協議,而XML是跨平臺的基礎。 跨編程語言和跨操作平臺:就是說服務端程序採用java編寫,客戶端程序則可以採用其他編程語言編寫,反之亦然!跨操作系統平臺則是指服務端程序和客戶端程序可以在不同的操作系統上運行。 遠程調用:就是一臺計算機a上的一個程序可以調用到另外一臺計算機b上的一個對象的方法,譬如,銀聯提供給商場的pos刷卡系統,商場的POS機轉賬調用的轉賬方法的代碼其實是跑在銀行服務器上。再比如,amazon,天氣預報系統,淘寶網,校內網,百度等把自己的系統服務以webservice服務的形式暴露出來,讓第三方網站和程序可以調用這些服務功能,這樣擴展了自己系統的市場佔有率。
WebService的三要素是:
SOAP (Simple Object Access Protocol):簡易對象訪問協議,soap用來描述傳遞信息的格式。
WSDL (WebServices Description Language):Web服務描述語言,用來描述如何訪問具體的接口。
UDDI (Universal Description Discovery and Integration):通用描述、發現及整合,用來管理、分發、查詢webService。
實現一個完整的Web服務包括以下步驟:
◆ Web服務提供者設計實現Web服務,並將調試正確後的Web服務通過Web服務中介者發佈,並在UDDI註冊中心註冊; (發佈)
◆ Web服務請求者向Web服務中介者請求特定的服務,中介者根據請求查詢UDDI註冊中心,爲請求者尋找滿足請求的服務; (發現)
◆ Web服務中介者向Web服務請求者返回滿足條件的Web服務描述信息,該描述信息用WSDL寫成,各種支持Web服務的機器都能閱讀;(發現)
◆ 利用從Web服務中介者返回的描述信息生成相應的SOAP消息,發送給Web服務提供者,以實現Web服務的調用;(綁定)
◆ Web服務提供者按SOAP消息執行相應的Web服務,並將服務結果返回給Web服務請求者。(綁定)
4.自定義webService服務端併發布服務編寫客戶端測試
①編寫服務接口
public interface WebServiceInterface { |
②編寫接口實現類
@WebService |
③編寫服務發佈類
public class WebServiceServer { //參數1:服務被訪問的url ip+端口號+服務名 //參數2:實現類 new WebServiceInterfaceImpl()); //查看WebService服務是否啓動 url+?wsdl //http://l27.0.0.1:9999/queryPhone?wsdl是否能顯示 } |
④ 驗證服務是否發佈成功
⑤執行wsimport生成客戶端代碼
⑥ 編寫客戶端調用服務端代碼
public class WebServiceClient {
|