天天看點

Java寫背景接口供别人調用

計算機語言分類有很多,如C、C++、C#、Java、Php、Python等等,她們有各自的特性及擅長的領域,但她們各自又不是全能的。在一個稍微大型一點的項目都會用到多種語言共同完成,那麼這些程式設計語言如何進行通信呢。什麼意思呢,就是比如說我Java寫的一個方法,其他程式設計語言要怎麼去調用呢?這就是本文要探讨的問題了。

一般來說,方法層面的程式設計語言通信用的是網絡接口形式,隻暴露出形參和結果供别人調用。接口一般分為接口定義者和接口調用者,定義者可以規定接收參數的類型及傳回形式,而接口定義者則隻能完全按照接口定義者規定的參數進行通路。就叫是我們所說的webService(網絡服務)。

以前的做法是利用XML作接口格式定義,然後通過Http做通訊和請求,如大名鼎鼎的SOAP,其實作在也是的,隻不過現在流行RestFul風格的Rest接口形式,但用的還是XML+HTTP,那這兩者有啥差別呢?最大的差別就是SOAP傳回的主要是XML格式,有時還需要附帶一些輔助檔案,而Rest則還可以傳回JSON類型的字元串,減少了很多繁亂的XML标簽。本文就以Java為例,用她寫一個接口,并讓其他人去調用,以此來簡單展示接口調用是怎麼樣一個過程。

步驟:

1、本機裝有Java JDK運作環境及程式設計IDE(如Myeclipse)

2、建立一個maven項目,用以下載下傳jar包,項目結構如下:

3 pom.xml檔案内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ws</groupId>
  <artifactId>restful</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>restful-server</name>
  <url>http://maven.apache.org</url>
  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jersey.version>2.6</jersey.version>
        <jersey-spring.version>2.23.1</jersey-spring.version>
        <spring.version>4.2.7.RELEASE</spring.version>
        <servlet-api-version>3.1.0</servlet-api-version>
        <logback.version>1.1.1</logback.version>
        <jcloverslf4j.version>1.7.6</jcloverslf4j.version>
    </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-spring3</artifactId>
            <version>${jersey-spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
 
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey-spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>${jersey-spring.version}</version>
        </dependency>
 
         <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-multipart</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-entity-filtering</artifactId>
            <version>${jersey.version}</version>
        </dependency>
 
        <!-- Spring4.2 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
 
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet-api-version}</version>
            <scope>provided</scope>
        </dependency>
 
        <!-- Logback dependencies -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${jcloverslf4j.version}</version>
        </dependency>
    
  </dependencies>
  <build>
    <finalName>restful</finalName>
  </build>
</project>
           

4 applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
 
    <context:component-scan base-package="com.kendy.*"></context:component-scan>
</beans>
           

5 web.xml則主要配置采用的容器、日志管理及攔截器,攔截器可以實作到達請求鄭濤之前進行身份認證,踢除沒有通路資格的請求,而rest項目一般是用Jersey容器。配置如下:(kendy隻是我的英文名,你們可以自己定義路徑)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>
  <servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>
            org.glassfish.jersey.servlet.ServletContainer
        </servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.kendy.filter.RestJaxRsApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>
           

6 攔截器如下:

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map.Entry;
 
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.Provider;
 
/**
 * 攔截請求
 */
@Provider
public class MyFilter implements ContainerRequestFilter {
 
  @Override
  public void filter(ContainerRequestContext context) throws IOException {
    
    //列印出所有請求頭
    MultivaluedMap<String, String> map =  context.getHeaders();
    for(Entry<String, List<String>> entry : map.entrySet()){
        String key = entry.getKey();
        List<String> valueList = entry.getValue();
        String values = valueList.toString();
        System.out.println(key + ":"+values.substring(1,values.length()-1));
    }
           

7 注冊Jersey容器所要管理的類

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.glassfish.jersey.server.ResourceConfig;
 
import com.kendy.restful.AccountManager;
import com.kendy.restful.AuthorityManager;
import com.kendy.restful.CardManager;
import com.kendy.restful.DeviceManager;
import com.kendy.restful.UserResource;
 
/**
 * ${DESCRIPTION}
 */
public class RestJaxRsApplication extends ResourceConfig {
 
    /**
     * Register JAX-RS application components.
     */
    public RestJaxRsApplication() {
 
        //服務類所在的包路徑
        packages("com.kendy.*");
        
        // register application resources
        this.register(YouClass.class);
     
        // register filters
        this.register(MyFilter.class);
        //this.register(RequestContextFilter.class);
        
        register(JacksonJsonProvider.class);
        //register(MultiPartFeature.class);
    }
}
           

8 接口定義(Restful風格)

package com.kendy.restful;
 
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
import org.springframework.stereotype.Component;
 
@Component
@Path("/CardManager")
public class CardManager {
    
    private SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
    @POST
    @Path("size")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String,Object> size(){
        Map<String,Object> map = new HashMap<>();
        //do something here
        map.put("Size", 1024);
        return map;
    }
    
    @POST
    @Path("getDetail")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Map<String,List<Map<String,Object>>> getDetail(){
        Map<String,List<Map<String,Object>>> map = new HashMap<>();
        //do something here
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> subMap = new HashMap<>();
        subMap.put("UUID", 10086);
        subMap.put("CardID", 10081);
        subMap.put("StartTime", sdf.format(new Date()));
        subMap.put("EndTime", sdf.format(new Date()));
        list.add(subMap);
        map.put("Card", list);
        
        return map;
    }
}
           

9 調用接口,有多種方式,本文用HttpClient

/**
     * 發送 post請求webService接口
     * @param url 通路的接口位址
     * @param account 使用者名
     * @param code 密碼
     * @param param 查詢參數
     * @return HttpResponse 該類包含請求方法的态碼及傳回的資料
     */  
    public static HttpResponse post(String url,String account,String code,Map<String,Object> param) {  
        //建立HttpClient執行個體及Post方法
        HttpClient httpclient = new DefaultHttpClient();  
        HttpPost httppost = new HttpPost(url); 
        //對使用者密碼MD5加密
        code = getMD5(code);
        //添加相關請求頭,依情況而定
        httppost.setHeader("Authorization","WSSE profile=\"UsernameToken\"");  
        httppost.setHeader("X-WSSE","UsernameToken Username=\""+account+"\",PasswordDigest=\""+code+"\"");  
        httppost.addHeader("Content-type","application/json; charset=utf-8");  
        httppost.setHeader("Accept", "application/json");  
        httppost.setHeader("Connection","keep-alive");  
        httppost.setHeader("Accept-Encoding","gzip");  
        httppost.setHeader("Accept-Language", "zh-CN,en,*");  
        httppost.setHeader("User-Agent","Mozilla/5.0"); 
        //傳遞請求參數
        String paramJsonStr = JSON.toJSONString(param);
        if(param != null)
            httppost.setEntity(new StringEntity(paramJsonStr, Charset.forName("UTF-8")));  
        HttpResponse response = null;
        try {  
            //執行post請求
            response = httpclient.execute(httppost);  
        } catch (Exception e) {  
            e.printStackTrace();  
        } 
        return response;
    }  
           

10 傳回接口

Java寫背景接口供别人調用

11 最後通過Map、List和Json工具對傳回來的字面量進行各種處理。

/**
     * 将從接口傳回的JSON資料轉換為實體集合等待插入資料表
     * 實體 IgmAccessControlChannelModel --> IGM_ACCESSCONTROL_CHANNEL
     *        IgmStationDoorModel --> IGM_STATION_DOOR
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private Map<String,Object> getDeviceEntityList(String data){
        Map<String,Object> totalMap = new HashMap<>();
        //把以下三個結果放到totalMap裡傳回
        List<IgmAccessControlChannelModel> accessControlList = new ArrayList<>();
        List<IgmStationDoorModel> doorList = new ArrayList<>();
        List<String> deviceIds = new ArrayList<>();
        
        IgmAccessControlChannelModel accessControlModel = null;
        IgmStationDoorModel stationDoorModel = null;
        
        Map map = JSON.parseObject(data, Map.class);
        map = (Map<String,List<Map<String,Object>>>)map;
        List<Map<String,Object>> deviceList = (List<Map<String, Object>>) map.get("Device");
        
        for(Map<String,Object> deviceMap : deviceList){
            String deviceId = (String)(deviceMap.get("DeviceID")+"");
            Object channels = deviceMap.get("Channels");
            List<Map<String,Object>> channelList = (List<Map<String,Object>>)channels;
            
            String id = ""; //用于設定igmaccessControlchannel表和igmstationDoor表的stationDoorid
            //判斷該門禁裝置ID在本平台是否比對
            boolean isMatched = isDeviceIdMatched(deviceId);
            
            if(isMatched){
                for(Map<String,Object> chnnelMap : channelList){
                    accessControlModel = new IgmAccessControlChannelModel();
                    stationDoorModel = new IgmStationDoorModel();
                    for(Map.Entry<String, Object> entry : chnnelMap.entrySet()){
                        String key =  entry.getKey().trim();
                        String value = "";
                        if(key.equals("Channel")){
                            value =(Integer)entry.getValue()+"";
                        }else{
                            value = (String)entry.getValue();
                        }
                        
                        switch(key){
                        case "Channel":
                            accessControlModel.setCommandCode(Integer.parseInt(value));
                            accessControlModel.setControlChannelName("控制通道"+value);
                            stationDoorModel.setDoorCode(value);
                            break;
                        case "Description":
                            stationDoorModel.setStationDoorName(value);
                            break;
                        default: break;
                        }
                    }
                    id = UUID.randomUUID().toString();
                    
                    accessControlModel.setAccessControlChannelId(UUID.randomUUID().toString());
                    accessControlModel.setDeviceId(deviceId);
                    accessControlModel.setStationDoorId(id);
                    
                    stationDoorModel.setStationDoorId(id);
                    stationDoorModel.setDeviceId(deviceId);
                    stationDoorModel.setRemark("指紋門禁");
                    
                    accessControlList.add(accessControlModel);
                    doorList.add(stationDoorModel);
                }
                deviceIds.add(deviceId);
            }else{
                //deviceId不比對的跳過
            }
        }
           

--------------------- 

作者:greatkendy123 

來源:CSDN 

原文:https://blog.csdn.net/greatkendy123/article/details/52818466 

版權聲明:本文為部落客原創文章,轉載請附上博文連結!