最近整理了一些开发中常用的技术,分享一下个人的心得,如有不对之处,欢迎指出。
目录
1.shiro权限控制在项目中的使用
2.java反射技术比较实体类字段的不同
3.jeesite框架Apache Commons Email的使用
4.jeesite框架excel表的导入导出
5.json对象和字符串的相互转换
5.1 jsp页面中json对象和字符串的转换
5.2 java代码中json对象和字符串的转换
6.JackJson的objectMapper的json对象化
7.Websocket的基本使用
8.webService的基本使用
1.jsp页面导入shiro标签库
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
标签库定义在shiro-web.jar包下的META-INF/shiro.tld中定义。
2.常用shiro标签
hasRole标签
拥有角色admin
如果当前Subject有角色将显示span内容。
hasAnyRoles标签
拥有角色admin
如果当前Subject有任意一个角色(或的关系)将显示span内容。
lacksRole标签
没有有角色abc
如果当前Subject没有角色abc将显示span内容。
hasPermission标签
拥有权限user:create
如果当前Subject有权限将显示span内容。
lacksPermission标签
没有有权限user:create
如果当前Subject没有权限将显示span内容。
在java后台代码中如何通过shrio根据用户的角色不同对数据进行过滤,需要结合shiro的subject对象和实体类中sqlMap进行sql语句的拼接来达到数据的过滤
Java代码
xml中sql拼接
注意:在原来的jeesite框架中每个实体类都继承了BaseEntity基类,而基类中已经加入了Map类型的sqlMap,所以每个继承了BaseEntity类都可以直接调用 getSqlMap方法若没有需自己重写
@JsonIgnore
@XmlTransient
public Map
if (sqlMap == null){
sqlMap = Maps.newHashMap();
}
return sqlMap;
}
public void setSqlMap(Map
this.sqlMap = sqlMap;
}
Java代码:
1.存放不同信息的类
public class ChangeInfo extends DataEntity {
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 ListcompareDetails(Object obj){
//存放新旧对象改变的内容
List list = new ArrayList();
//新的对象
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 diffList) {
Map diffMap = new HashMap();
//map存储中英文对应
for (int i = 0; i < diffMemberArray.length; i++) {
diffMap.put(diffMemberArray[i], diffMemberName[i]);
}
//英文List
List 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();
}
}
1.导入相关依赖
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-emailartifactId>
<version>1.2version>
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="您好"+""+"欢迎注册XX"+";
Map map = new HashMap();
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 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!");
}
}
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>${poi.version}version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>${poi.version}version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxml-schemasartifactId>
<version>${poi.version}version>
dependency>
2.实体类添加ExcelFiled注解
注:只有添加@ExcelField注解才能在导入导出的时候将字段映射
5 导入excel表数据
使用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方法来代替。
/** * 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);
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.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.5.3version>
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")。
1.pom.xml文件添加依赖jar包
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-websocketartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-messagingartifactId>
<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 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> 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{
ListsocketSessionList=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是个不错的选择,可以多媒体聊天、文字聊天以及其它优势如与别人合作一起在公共数字黑板上画画。
1.webService介绍
W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计。Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执行远程系统的请求服务。简单的说:WebService即Web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术。
Web服务:基于HTTP和XML的技术,HTTP是互联网上应用最为广泛的一种网络协议,而XML是跨平台的基础。 跨编程语言和跨操作平台:就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。 远程调用:就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,银联提供给商场的pos刷卡系统,商场的POS机转账调用的转账方法的代码其实是跑在银行服务器上。再比如,amazon,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,这样扩展了自己系统的市场占有率。
2.webService的三要素
WebService的三要素是:
SOAP (Simple Object Access Protocol):简易对象访问协议,soap用来描述传递信息的格式。
WSDL (WebServices Description Language):Web服务描述语言,用来描述如何访问具体的接口。
UDDI (Universal Description Discovery and Integration):通用描述、发现及整合,用来管理、分发、查询webService。
3.调用原理
实现一个完整的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 {
|