https+xml服务端/客户端java后台编写及soapUI https测试

一、https+xml服务端编写

1.1 创建证书文件

1.1.1 创建服务器KeyStore

keytool -genkey -alias server_jks_cennavi -keyalg RSA -keypass 123456 -storepass 123456 -keystore server.jks -validity 3650

1.1.2 导出服务端证书

keytool -export -trustcacerts -alias server_jks_cennavi  -file server.cer -keystore  server.jks -storepass 123456

1.1.3 创建客户端KeyStore

keytool -genkey -alias client_p12_cennavi -keyalg RSA -keypass 123456 -storepass 123456 -keystore client.p12 -validity 3650 -storetype PKCS12

1.1.4 导出客户端Cer证书

keytool -export -trustcacerts -alias client_p12_cennavi  -file client.cer -keystore  client.p12 -storepass 123456 -storetype PKCS12

1.1.5 交换证书

交换导入服务端和客户端证书,作为双方信任证书。
keytool -import -trustcacerts -alias client_p12_cennavi -file client.cer -keystore server.jks
keytool -import -trustcacerts -alias server_jks_cennavi -file server.cer -keystore client.jks

1.2 tomcat https配置


注:以上配置为https双向验证,若只要https服务端的单向验证,则将clientAuth="true" 和truststoreFile="C:\Users\hsinghsu\server.jks" truststorePass="123456" 配置去掉即可。

1.3 服务端java代码编写

1.3.1 编写servlet服务端代码

编写servlet代码,用于获取用户https+xml/http+xml请求,解析请求后进行相应业务为逻辑处理返回相应信息给请求方。
package com.hsinghsu.test.web.servlet;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class TestInterfaceServlet extends HttpServlet
{
    
    /**
     * 对外接口主入口
     * 用于获取用户请求,返回用户请求使用。
     */
    public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException
    {
        HttpServletResponse httpResponse = (HttpServletResponse)response;
        HttpServletRequest httprequest = (HttpServletRequest)request;
        httpResponse.setContentType("text/html;charset=UTF-8");
        
        Map mapHeader = getHeaderMap(httprequest);// 获取http头信息
        
        String requestXml = "";//请求过来的xml报文
        String responseXml = "";//返回的xml报文
        Document doc = null;
        
        InputStream is = request.getInputStream();
        System.out.println("======http header timestamp is :" + mapHeader.get("timestamp"));
        
        SAXReader saxReader = new SAXReader();
        Map map = new HashMap();
        
        try
        {
            doc = saxReader.read(is);
            requestXml = doc.asXML();
            System.out.println("======request xml :" + requestXml);
            Element rootElm = doc.getRootElement();//从root根节点获取请求报文
            map = parseXML(rootElm, new HashMap());
            
            String msgname = map.get("msgname");//从http body中获取到的msgname值
            
            // 是否https访问
            if (request.isSecure())
            {
                //https访问
                if ("loginReq".equals(msgname))
                {
                    System.out.println("the https+xml request is loginReq");
                    responseXml =
                        "loginRep1.0.00成功111";
                }
                else
                {
                    System.out.println("请求接口名称不在本系统内");
                    responseXml =
                        "1.0.01请求接口名称不在本系统内";
                }
            }
            else
            {
                //http访问  
                if ("logOutReq".equals(msgname))
                {
                    System.out.println("the http+xml request is logOut");
                    responseXml =
                        "logOutRep1.0.00成功111";
                }
                else
                {
                    System.out.println("请求接口名称不在本系统内");
                    responseXml =
                        "1.0.01请求接口名称不在本系统内";
                }
            }
            
        }
        catch (Exception e1)
        {
            System.out.println("请求数据不正确");
            responseXml =
                "1.0.02请求数据不正确";
            
        }
        
        // 对报文进行压缩处理
        String AcceptEncoding = "gzip";
        if (mapHeader != null)
            AcceptEncoding = mapHeader.get("Accept-Encoding");
        if (null != AcceptEncoding && "gzip".equals(AcceptEncoding))
        {
            // 使用gzip压缩报文
            System.out.println("======output response xml with gzip is : " + responseXml);
            response.getOutputStream().write(gZip(responseXml.getBytes()));
            response.getOutputStream().flush();
            response.getOutputStream().close();
        }
        else
        {
            // 不压缩报文,直接传输
            System.out.println("======output response xml without gzip is : " + responseXml);
            response.getOutputStream().write(responseXml.getBytes());
            response.getOutputStream().flush();
            response.getOutputStream().close();
        }
        
    }
    
    /**
     * 获取http头信息 
     * <功能详细描述>
     * @param request
     * @return
     * @see [类、类#方法、类#成员]
     */
    public Map getHeaderMap(HttpServletRequest request)
    {
        Map map = new HashMap();
        if (null != request.getHeader("msgname") && !"".equals(request.getHeader("msgname")))
            map.put("msgname", request.getHeader("msgname"));
        if (null != request.getHeader("Accept-Encoding") && !"".equals(request.getHeader("Accept-Encoding")))
            map.put("Accept-Encoding", request.getHeader("Accept-Encoding"));
        if (null != request.getHeader("timestamp") && !"".equals("timestamp"))
            map.put("timestamp", request.getHeader("timestamp"));
        return map;
    }
    
    /**
     * 将xml解析成map键值对
     * <功能详细描述>
     * @param ele 需要解析的xml对象
     * @param map 入参为空,用于内部迭代循环使用
     * @return
     * @see [类、类#方法、类#成员]
     */
    private Map parseXML(Element ele, Map map)
    {
        for (Iterator i = ele.elementIterator(); i.hasNext();)
        {
            Element node = (Element)i.next();
            System.out.println("======parseXML node name:" + node.getName());
            if (node.attributes() != null && node.attributes().size() > 0)
            {
                for (Iterator j = node.attributeIterator(); j.hasNext();)
                {
                    Attribute item = (Attribute)j.next();
                    System.out.println("======parseXML property name:" + item.getName() + " property value:"
                        + item.getValue() + "\n");
                    map.put(item.getName(), item.getValue());
                }
            }
            if (node.getText().length() > 0)
            {
                System.out.println("======parseXML node value:" + node.getText());
                map.put(node.getName(), node.getText());
            }
            if (node.elementIterator().hasNext())
            {
                parseXML(node, map);
            }
        }
        return map;
    }
    
    /**
     * gZip压缩方法
     * 将原报文通过gzip压缩
     * @param data
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static byte[] gZip(byte[] data)
    {
        byte[] b = null;
        try
        {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            GZIPOutputStream gzip = new GZIPOutputStream(bos);
            gzip.write(data);
            gzip.finish();
            gzip.close();
            b = bos.toByteArray();
            bos.close();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return b;
    }
    
}

1.3.2 web.xml配置

在web.xml中配置访问该接口的servlet,详见配置如下:

	interfaceServlet
	com.hsinghsu.test.web.servlet.TestInterfaceServlet


	interfaceServlet
	/interface

注:如果在servlet中需要注入service/dao的bean,请参见:http://www.it165.net/pro/html/201307/6589.html 【如何用Spring将Service注入到Servlet中(注解模式)】

1.3.3 启动服务端

启动服务端tomcat。服务端的访问地址为:https://127.0.0.1:8843/testhttps/interface

二、https+xml客户端编写

2.1 编写客户端java代码,示例如下:

package com.hsinghsu.test.web.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;

public class TestReqServlet extends HttpServlet
{
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
//        String sURL = "http://127.0.0.1:8080/testhttps/interface";
        String sURL = "https://127.0.0.1:8443/testhttps/interface";
        String xml =
            "loginReq20140422094111112255";
        toHTTPS(sURL, xml);
    }
    
    
    /**
     * https调用
     * <功能详细描述>
     * @param sURL 请求URL
     * @param xml 请求报文
     * @return
     * @throws IOException
     * @see [类、类#方法、类#成员]
     */
    public String toHTTPS(String sURL, String xml)
        throws IOException
    {
        sURL = "https://127.0.0.1:8443/testhttps/interface";
        
        System.setProperty("javax.net.ssl.trustStore", "C:\\Users\\hsinghsu\\Desktop\\https\\client.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
        System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");
        System.setProperty("javax.net.ssl.keyStore", "C:\\Users\\hsinghsu\\Desktop\\https\\client.p12");
        System.setProperty("javax.net.ssl.keyStorePassword", "123456");
        //注:去掉以上5行则表示使用http协议访问
        
        String resultXML = "";
        HttpClient httpClient = null;
        PostMethod postMethod = null;
        try
        {
            httpClient = new HttpClient();
            // 设置超时时间
            httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
            httpClient.getHttpConnectionManager().getParams().setSoTimeout(30000);
            postMethod = new PostMethod(sURL);
            postMethod.setRequestEntity(new StringRequestEntity(xml, "text/html", "UTF-8"));
            
            postMethod.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
            postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
            int statusCode = httpClient.executeMethod(postMethod);
            if (statusCode != HttpStatus.SC_OK)
            {
                System.out.println("Call method failed: " + postMethod.getStatusLine());
            }
            BufferedReader in = null;
            try
            {
                in = new BufferedReader(new InputStreamReader(postMethod.getResponseBodyAsStream(), "utf-8"));
                SAXReader saxReader = new SAXReader();
                Document doc = saxReader.read(new InputStreamReader(postMethod.getResponseBodyAsStream(), "utf-8"));
                resultXML = doc.asXML();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (in != null)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (postMethod != null)
            {
                postMethod.releaseConnection();
            }
        }
        return resultXML;
    }
    
}
配置完成后使用servlet访问即可测试

三、soapUI测试https+xml接口

打开soapUI,File-->Preferences-->SSL Settings,导入client.p12,输入密码即可
注:以上配置为https双向验证,若只要https服务端的单向验证,则去掉client.p12 SOAPUI配置证书即可。

你可能感兴趣的:(Web)