当前位置 : 主页 > 网页制作 > Nodejs >

WebService学习总结十一 使用Ajax访问WebService和使用HttpURLConnection访问WebService

来源:互联网 收集:自由互联 发布时间:2021-06-24
原始js,访问WebService会存在跨域无法访问的问题,可以使用ajax请求一个Servlet,在Servlet使用HttpURLConnection放问WebService,解决ajax直接访问WebService带来的跨域问题。 一 js下的ajax访问WebService 服

原始js,访问WebService会存在跨域无法访问的问题,可以使用ajax请求一个Servlet,在Servlet使用HttpURLConnection放问WebService,解决ajax直接访问WebService带来的跨域问题。

一 js下的ajax访问WebService

服务器端

先导入cxf的包。

自定义拦截器(不需要不用加)

package ws.server.interceptor;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
/**
 * 检查用户名称和密码
 * @author
 *
 */
public class MyServerInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

	public MyServerInterceptor() {
		super(Phase.PRE_PROTOCOL);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		// 读header里的数据
		Header header=msg.getHeader(new QName("atguigu"));//参数和客户端传的一样
		if(header!=null){
			Element atguigu=(Element) header.getObject();
			String name=atguigu.getElementsByTagName("name").item(0).getTextContent();
			String pwd=atguigu.getElementsByTagName("pwd").item(0).getTextContent();
			System.out.println("name|pwd:::::::::::::::::::::::::::::::::::"+name+"|"+pwd);
			if(name.equals("zhangsan")&&pwd.equals("123")){
				System.out.println("server:check ok");
				return;
			}
		}
		//没通过校验,抛出异常
		System.out.println("没有通过校验-------------------------------------------");
		throw new Fault(new RuntimeException("用户名或密码不对"));
	}

}

UserBean.java

package ws.spring.server;

public class UserBean {
	private int id;
	private String name;
	
	public UserBean(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "UserBean [id=" + id + ", name=" + name + "]";
	}
	
}


SEI接口

package ws.spring.server;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public interface UserWS {
	@WebMethod
	public UserBean getUserById(int id);
}

接口实现

package ws.spring.server;

import javax.jws.WebService;

@WebService
public class UserWSImpl implements UserWS {
	public UserWSImpl(){
		System.out.println("初始化 UserWSImpl");
	}
	@Override
	public UserBean getUserById(int id) {
		System.out.println("server getUserById:"+id);
		return new UserBean(1, "张三");
	
	}

}


cxf框架的配置(beans.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:jaxws="http://cxf.apache.org/jaxws"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws">
  
  
  <!-- 引cxf的一些核心配置 -->
   <import resource="classpath:META-INF/cxf/cxf.xml" /> 
   <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
   <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> 
   
   <jaxws:endpoint 
     id="userWS" 
     implementor="ws.spring.server.UserWSImpl" 
     address="/userws">
     	<jaxws:inInterceptors>
     		<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
     		<bean class="ws.server.interceptor.MyServerInterceptor"></bean>
     	</jaxws:inInterceptors>
     	<jaxws:outInterceptors>
     		<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
     	</jaxws:outInterceptors>
    </jaxws:endpoint>
     
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ws_ajax_server</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
   <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
         org.springframework.web.context.ContextLoaderListener
      </listener-class>
  </listener>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
         org.apache.cxf.transport.servlet.CXFServlet
      </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>


客户端

导入jar包;

生成客户端代码:

GetUserById.java
GetUserByIdResponse.java
ObjectFactory.java
package-info.java
UserBean.java
UserWS.java
UserWSImplService.java

自定义的客户端拦截器:

package ws.client.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.xml.utils.DOMHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class MyClientInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	//自定义的校验字段,姓名和密码
	private String name;
	private String pwd;
	
	public MyClientInterceptor(String name,String pwd) {
		super(Phase.PRE_PROTOCOL);//配置拦截时机,一定要有,准备协议化得时候拦截
		this.name=name;
		this.pwd=pwd;
	}

	//封装数据到消息里,格式如下
	/*    <Envelop>
	 * 			<head> //里面的标签可以有多个
	 * 				<atguigu>  //自定义标签,随意
	 * 					<name>zhangsan</name>
	 * 					<pwd>123123</pwd>
	 * 				</atguigu>
	 * 				<atguigu1>  //自定义标签,随意
	 * 					<name>zhangsan</name>
	 * 					<pwd>123123</pwd>
	 * 				</atguigu1>
	 * 			</head>
	 * 			<body>
	 * 				<sayHello>
	 * 					<arg0>BOB</arg0>
	 * 				</sayHello>
	 * 			</body>
	 * 	  </Envelop>
	 * 
	 * 
	 * 
	 * 
	 *
	 *
	 *
	 *
	 */
	@Override
	public void handleMessage(SoapMessage msg) throws Fault {
		List<Header> headers=msg.getHeaders(); //创建Head
		//创建head里的元素,添加到head
		Document document=DOMHelper.createDocument();
		Element atguigu=document.createElement("atguigu");
		
		Element name=document.createElement("name");
		name.setTextContent(this.name);
		atguigu.appendChild(name);
		
		Element pwd=document.createElement("pwd");
		pwd.setTextContent(this.pwd);
		atguigu.appendChild(pwd);
		
		headers.add(new Header(new QName("atguigu"), atguigu));//QName里的参数要和标签名一样
		System.out.println("client:handleMessage");
	}

}

客户端的配置(client-beans.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:jaxws="http://cxf.apache.org/jaxws"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
   	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws">
	<jaxws:client id="userClient" 
		serviceClass= "ws.spring.server.UserWS" 
		address= "http://localhost:8080/ws_ajax_server/userws">	
		<!-- 添加客户端出拦截器 -->
		<jaxws:outInterceptors>
			<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
			<bean class="ws.client.interceptor.MyClientInterceptor">
				<constructor-arg name="name" value="zhangsan"/>
				<constructor-arg name="pwd" value="123"/>
			</bean>
		</jaxws:outInterceptors>
	</jaxws:client>
</beans>


jNewFile.sp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script type="text/javascript">
	
	function ajaxFunc(){
		var name=document.getElementById("uid").value;
		var data='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><atguigu><name>zhangsan</name><pwd>123</pwd></atguigu></soap:Header><soap:Body><ns2:getUserById xmlns:ns2="http://server.spring.ws/"><arg0>'+name+'</arg0></ns2:getUserById></soap:Body></soap:Envelope>';
	
		var req=getxmlHttp();
	
		req.onreadystatechange=function(){		
			if(req.readyState==4 && req.status==200) {
				
				var result=req.responseXML;// 返回xml数据 ,alert(req.responseText);可以以文本形式查看返回xml内容,再解析
			//	alert(req.responseText);
				var ret=result.getElementsByTagName("name")[0];
			
				var res=ret.firstChild.data;
				alert(res); 
				
			}
		}
		req.open("POST","http://localhost:8080/ws_ajax_server/userws");
		req.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		req.send(data);
	}

	function HttpURLConnectionFunc(){
		var name=document.getElementById("uid").value;
		var data='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><atguigu><name>zhangsan</name><pwd>123</pwd></atguigu></soap:Header><soap:Body><ns2:getUserById xmlns:ns2="http://server.spring.ws/"><arg0>'+name+'</arg0></ns2:getUserById></soap:Body></soap:Envelope>';
		
		var req=getxmlHttp();
	
		req.onreadystatechange=function(){			
			if(req.readyState==4 && req.status==200) {				
				var result=req.responseXML;// 返回xml数据 ,alert(req.responseText);可以以文本形式查看返回xml内容,再解析
			
				var ret=result.getElementsByTagName("name")[0];
				var res=ret.firstChild.data;
				alert(res); 				
			}
		}
		req.open("POST","HttpURLConnectionServlet");
		req.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		req.send("data="+data);
	}
	
	
	
	
	//XMLHttpRequest
	function getxmlHttp(){
		var xmlHttp = null;
		try {
			// Firefox, Opera 8.0+, Safari  chrome
			xmlHttp = new XMLHttpRequest();
		} catch (e) {
			// Internet Explorer
			try {
				xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		return xmlHttp;
	} 
</script>
</head>
<body>

	<input type="text" name="uid" id="uid"/>
	<button onclick="ajaxFunc()" >ajaxBut</button>	
	<button onclick="HttpURLConnectionFunc()" >HttpURLConnectionBut</button>	
</body>
</html>

点击ajaxBut按钮,可以使用ajax请求webService,由于WebService的发布路径是

http://localhost:8080/ws_ajax_server/userws
<span style="white-space:pre">	</span>当我们用http://IP/ws_ajax_client/NewFile.jsp登录页面

请求WebService时候,无法请求,IP 到Localhost存在跨域,虽然都是本机地址,仍是跨域。

但是把Ip换成localhost就可以访问了。


  二 解决Ajax不能跨域访问WebService问题:

我们想使用    http://192.168.1.103:8080/ws_ajax_client/NewFile.jsp 和 http://localhost:8080/ws_ajax_client/NewFile.jsp 都能访问WebService,可以先访问本地的Servlet,在Servlet使用HttpURLConnection请求webService.

      NewFile.jsp页面中的第二个按钮HttpURLConnectionBUtton就是使用的这种方式,对应的HttpURLConnectionServlet代码如下:

package servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//页面使用ajax把数据提交到这个Servlet,这个Servlet使用HttpServletRequest向WebService发送请求。请求结果返回,再返给页面
public class HttpURLConnectionServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String data=request.getParameter("data"); 
		System.out.println("------------------------------------------------");
		System.out.println(data); //获取页面提交的数据
		System.out.println("------------------------------------------------");
		URL url=new URL("http://localhost:8080/ws_ajax_server/userws");
		HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection() ;
		httpUrlConnection.setDoInput(true);
		httpUrlConnection.setDoOutput(true);
		httpUrlConnection.setRequestProperty("Content-type", "text/xml;charset=utf-8");
		OutputStream outputStream = httpUrlConnection.getOutputStream();
		outputStream.write(data.getBytes("UTF-8"));
		outputStream.flush();
		int responseCode = httpUrlConnection.getResponseCode();
		if(responseCode==200){ //服务器已成功处理了请求
			InputStream inputStream = httpUrlConnection.getInputStream();
			response.setContentType("text/xml;charset=utf-8");
			ServletOutputStream outputStream2 = response.getOutputStream();
			byte[] bs=new byte[1024];
			int len=0;
			while((len=inputStream.read(bs))>0){
				outputStream2.write(bs, 0, len);
			}
			outputStream2.flush();
			outputStream2.close();
			inputStream.close();
		}
		outputStream.close();
	}

}


此时使用Ip跨域访问,点击第二个按钮时候可以正确请求WebService了。

网友评论