一起谈.NET技术,JAVA与.NET的相互调用——TCP/IP相互调用基本架构

简介:   TCP/IP套接字的概念  TCP/IP(传输控制协议/网际协议)是网络互连的通信协议,通过它可以实现各种异构网络或异种机之间的互联通信。TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。

  TCP/IP套接字的概念

  TCP/IP(传输控制协议/网际协议)是网络互连的通信协议,通过它可以实现各种异构网络或异种机之间的互联通信。TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。TCP/IP是一个四层的分层体系结构。高层为传输控制协议,它负责聚集信息或把文件拆分成更小的包。低层是网际协议,它处理每个包的地址部分,使这些包正确的到达目的地。 TCP/IP已成为当今计算机网络最成熟、应用最广的互联协议。Internet采用的就是 TCP/IP协议,网络上各种各样的计算机上只要安装了TCP/IP协议,它们之间就能相互通信。

  TCP/IP套接字通讯的开发

  在众多的开发语言中,绝大部分的开发语言都支持TCP/IP协议通讯,开发过程也十分相像,先设置好Socket,然后由客户端发送请求信息,服务器连接客户端接收到请求后再返还信息。而在.NET系统当中则稍有不同,系统把Socket对象包装在TcpClient对象内,对Socket对象的生命周期进行管理。在开发过程当中,服务器与客户端的开发语言有所不同的情况经常发生,服务器是在JDK1.6的环境下进行开发的,客户却要求使用.NET开发客户端,这往往会令开发人员感到困惑!下面在下使用JAVA为服务器,.NET为客户端为例子,为大家介绍一下如何使用TCP/IP协议进行JAVA  .NET之间的相互调用。像TCP/IP实现聊天室这样的例子很多,开发起来也比较简单,因为通讯双方都是使用String来传送信息。而在真正建立ERP、OA、CRM等系统的时候,通讯双方都必须先建立一套统一的通讯契约,才能实现TCP/IP通讯,下面将为大家介绍一个比较典型的企业信息通讯实例。

  信息传送方式

  因为.NET与JAVA各有不同的特性,双方不可能直接通过的序列化对象来传输信息,常用的信息交换方式有以下三种:

  1. 最 笨拙也是最复杂的一种传息方式,就是直接使用“头文件说明+字段属性”的方式。 这是一个既原始又麻烦的通讯方式,因为每个契约都要以二进制的方式发送一个请求,就算是同一类契约,随着参数的不同,每个请求的长度也会发生改变。这样的 传息方式虽然是麻烦,但在不同开发语言相互调用的时候却经常会看到,这可能是因为开发人员对两种开发语言未能完全熟悉,所以倒置使用这最原始最简单的开发 方式。

  2. 使用XML的信息传送方式,这是最常见,使用最广的信息传递方式。在绝大多数的开发平台都会支持XML,所以XML在Web网络传讯过程中最为常见。但XML最大的一个缺点就是过于堪舆,耗费大量的传输流量。

  3. 对 于XML的缺点,JSON应运而生而且发展迅速,JSON本是源于Javascript的,多数只用于B/S的页面开发,但随着技术的发展和多个开发语言 的支持,现今到处都可以看JSON的身影。因为JSON既提供一套跨平台的通讯方式,也免去XML复杂特性,受到各类型开发人员的欢迎。

  服务器端开发

  • 通讯契约

  首先建立一套服务器与客户端同时接受通讯契约, Contract 的name特性是契约的名称,服务器会通过此名称在Contracts.xml文件中找到该契约,然后根据output的package属性,class属性,method属性找到该契约的包名称,类名,调用的方法等属性。

 
 
< Contracts >
< Contract name ="GetPersonByAge" > //name为契约名,服务器与客户端必须同时遵守此契约
< Input >
< Description > 获取Age等于此值的People对象集 </ Description > //说明此契约内容
</ Input >
< Output >
< Package > Manager </ Package > //接收到GetPersonByAge请求时所调用的包名称
< Class > PersonManager </ Class > //接收到GetPersonByAge请求时所调用的类名称
< Method > GetListByAge </ Method > //接收到GetPersonByAge请求时所调用的处理方法名称
</ Output >
</ Contract >
< Contract name ="GetPersonByID" >
< Input >
< Description > 获取ID等于此值的People对象 </ Description >
</ Input >
< Output >
< Package > Manager </ Package >
< Class > PersonManager </ Class >
< Method > GetListByID </ Method >
</ Output >
</ Contract >
</ Contracts >
  • 以JSON方式实现信息传送

  尽管目前在C/S的开发当中大部分还是使用序列化对象和分节字段的方式进行双方通讯,但在这个实例当中,在下想以JSON通讯方式为例子来实现。首先,客户端会使用额定格式的JSON向服务器发送请求:

 
 
{“ContractName”:“GetPeopleByAge”,“Params”: [ 23 ] }

  ContractName代表着契约名称,系统会根据此名称在Contracts.xml文件中找到Name等于GetPeopleByAge的Contract项。然后在对应Output的子项Package,Class,Method中查找到对应的包,类型和方法。

  Params是客户端传输过来的参数,服务器端会调用对象的方法输入参数23后,得到计算结果,最后把结果返还到客户端。

  在 这里有两点是值得注意的,第一点是JSON中的契约格式是固定的,服务器与客户端都必须遵守此契约,在ContractName中输入是必须对应的契约名 称,而在Params中输入的必输是一个参数的集合,哪怕里面只包含有一个参数。第二点是在Contracts.xml文件,Output里面的 Package,Class,Method是服务器端自定义的,它只是绑定了服务器端实现GetPersonByAge契约的方法,而这些方法并不是固 定,服务器可以根据系统的需要而修改。这个做法有点像Struts里面的Struts.xml文件,其意义就是在于使服务器的处理方法与客户端发送的请求实现分离。

  • 基本结构

  系统的基本结构如图,客户端会以JSON方式{“ContractName”:“GetPeopleByAge”,“Params”:[23]}发送请求到服务器,服务器会利用“数据转换层”把接收到的请求转换成Contract对象。然后逻辑转换层会根据该Contract对象调用对应的方法,最后把计算结果以JSON方式返回到客户端。

  注意在服务器与客户端信息交换的过程中,都是使用JSON格式。

  • JSON数据转换

  在服务器端,当接到到客户端请求后,Transfer类负责把接收到的JSON数据转换成Contract对象。在Transfer里面使用org.json工具包作为JSON的转化工具,org.json工具包可于以下网址下载http://www.json.org/java/index.html

  而Implement类包含GetResult(Contract contract )方法,其作就是根据contract对象Package,Class,Method等属性,调用“逻辑转换层”的对应方法,最后把计算结果返还给InputControl。

  服务器端接收请求后就会直接调用InputControl对输入的数据进行处理。

 
 
// Contract实体类,包含契约的package,class,method,params等多个属性
package Model;

import org.json.JSONArray;

public class Contract {
private String package1;
private String class1;
private String method;
private JSONArray params ;
public void setPackage1(String package1) {
this .package1 = package1;
}
public String getPackage1() {
return package1;
}
public void setClass1(String class1) {
this .class1 = class1;
}
public String getClass1() {
return class1;
}
public void setMethod(String method) {
this .method = method;
}
public String getMethod() {
return method;
}
public void setParams(JSONArray params ) {
this . params = params ;
}
public JSONArray getParams() {
return params ;
}

}

// 把输入的String字符串转化为Contract对象
// 在这里使用org.json工具包作为JSON的转化工具,org.json工具包可于以下网址下载http: // www.json.org/java/index.html
package Common;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import Model.Contract;
import org.json.
* ;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Transfer {
private Transfer(){}

private static String contractName = null ;
private static Contract contract = new Contract();
private static JSONObject jsonObject = null ;

public static Contract GetContract(String data) throws Exception, JSONException, ParserConfigurationException, SAXException, IOException{
jsonObject
= new JSONObject(data); // 把字符串转化为JSONOject对象
GetContractName(); // 获取契约名称
GetProperty(); // 获取契约的package,class,method属性
GetParams(); // 获取契约的参数集
return contract;
}

/*
* 获取契约对应的包名称,类名称,方法名称
*/
private static void GetProperty() throws Exception{
File file
= new File( " Contracts.xml " );
DocumentBuilderFactory factory
= DocumentBuilderFactory.newInstance();
DocumentBuilder builder
= factory.newDocumentBuilder();
Document doc
= builder.parse(file);
NodeList nodeList
= doc.getElementsByTagName( " Contract " );
Element contractElement
= null ;
for ( int i = 0 ; i < nodeList.getLength(); i ++ ) {
if (nodeList.item(i).getAttributes().item( 0 ).getNodeValue().equals(contractName)){
contractElement
= (Element)nodeList.item(i);
break ;
}
}
if (contractElement != null ){
Element outputElement
= (Element)contractElement.getElementsByTagName( " Output " ).item( 0 );
contract.setPackage1(outputElement.getElementsByTagName(
" Package " ).item( 0 ).getTextContent());
// 获取包名称
contract.setClass1(outputElement.getElementsByTagName( " Class " ).item( 0 ).getTextContent());
// 获取类名称
contract.setMethod(outputElement.getElementsByTagName( " Method " ).item( 0 ).getTextContent());
// 获取方法名
}
else
throw new Exception( " 未能找到对象的契约 " );
}

/*
* 获取契约名称
*/
private static void GetContractName() throws JSONException{
contractName
= jsonObject.getString( " ContractName " );
}

/*
* 获取输入参数
*/
private static void GetParams() throws JSONException{
contract.setParams(jsonObject.getJSONArray(
" Params " ));
}
}

// 调用Contract对象里面包中的类的某个方法,获取计算结果
package Common;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONArray;
import Model.
* ;

public class Implement {
private Contract contract;
private String fullName;
private static Map < String,Object > objects = new HashMap < String,Object > (); // 保存对象实体
private static Map < String,Class > classes = new HashMap < String,Class > (); // 保存类名

/*
* 先获取对应的对象,再用反射模式调用对象的方法,获取计算结果
*/
public Object GetResult(Contract contract){
this .contract = contract;
this .fullName = contract.getPackage1() + " . " + contract.getClass1();

try {
Object manager
= GetObject();
Class theClass
= classes. get (fullName);
Method method
= theClass.getDeclaredMethod(contract.getMethod(),JSONArray. class );
return method.invoke(manager, contract.getParams());
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null ;
}
}

/*
* 多次使用反射创建获取对象会损耗一定性能,所以此处使用单体模式获取对应的对象
*/
private Object GetObject() throws InstantiationException, IllegalAccessException, ClassNotFoundException{
if ( ! objects.containsKey(fullName)){
Class theClass
= Class.forName(fullName);
classes.put(fullName,theClass);
Object manager
= theClass.newInstance();
objects.put(fullName, manager);
}
return objects. get (fullName);
}
}

// 直接把接收到的二进制数据转换成String,然后通过Transfer把String转化为Contract对象,最后通过Implement获取运算结果
package Common;

import java.io.DataInputStream;
import Model.Contract;

public class InputControl {
private DataInputStream inputStream;

public InputControl(DataInputStream inputStream){
this .inputStream = inputStream;
}
/*
* 直接把接收到的二进制数据转换成String,然后通过Transfer把String转化为Contract对象,最后通过Implement对象获取运算结果
*/
public Object GetResult(){
byte [] byteMessage = new byte [ 1024 ]; // 在此处只获取测试数据,在真正运行时应使用分批缓存的方式
try {
int n = inputStream.read(byteMessage);
String message
= new String(byteMessage, " ASCII " );
Contract contract
= Transfer.GetContract(message);
Implement implement
= new Implement();
Object result
= implement.GetResult(contract);
return result;
}
catch (Exception ex){
ex.printStackTrace();
return null ;
}
}
}

  最后,系统通过OutputControl类把计算结果返还给客户端。

 
 
// 把计算结果返回到客户端
package Common;

import java.io.DataOutputStream;

public class OutputControl {
private DataOutputStream outputStream;

public OutputControl(DataOutputStream outputStream){
this .outputStream = outputStream;
}

public void Output(Object data){
try {
outputStream.writeBytes(data.toString());
outputStream.flush();
}
catch (Exception ex){
ex.printStackTrace();
}
}
}

// 运行系统进行测试
package Common;

import java.io.
* ;
import java.net.
* ;

public class Program {
private static ServerSocket serverSocket;

public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
Socket socket;
try {
serverSocket
= new ServerSocket( 5100 ); // 激活5100端口
while ( true ){ // 循环捕捉请求
socket = serverSocket.accept();
DataOutputStream outStream
= new DataOutputStream(socket.getOutputStream()); // 获取DataOutputStream输出流
DataInputStream inputStream = new DataInputStream(socket.getInputStream()); // 获取DataInputStream输入流

// 调用InputControl对象获取运算结果
InputControl inputControl = new InputControl(inputStream);
Object result
= inputControl.GetResult();
// 调用OutputControl对象输入运算结果
OutputControl outputControl = new OutputControl(outStream);
outputControl.Output(result);
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();

}
}
}
  • 逻辑转换层

  现在先开发一个例子作为参考,在完成客户端开发的时候就可以进行测试。这个例子是先在Manager包里面设置好一个类PersonManager,PersonManager类中包含一个名为GetListByAge的方法。在Contracts.xml文件设置一个名为GetPersonByAge的契约,客户端就可以通过这个契约在远程调用此方法获取计算结果。

 
 
// 设置Person对象
package Model;

public class Person {
private int id;
private String name;
private int age;
public void setId( int id) {
this .id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this .name = name;
}
public String getName() {
return name;
}
public void setAge( int age) {
this .age = age;
}
public int getAge() {
return age;
}
}

// 开发PersonManager
package Manager;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import Model.
* ;

public class PersonManager {
/*
* 测试数据
*/
private List < Person > GetList(){
List
< Person > personList = new ArrayList < Person > ();
Person person1
= new Person();
person1.setId(
0 );
person1.setAge(
23 );
person1.setName(
" Mike " );
personList.add(person1);

Person person2
= new Person();
person2.setId(
1 );
person2.setAge(
29 );
person2.setName(
" Leslie " );
personList.add(person2);

Person person3
= new Person();
person3.setId(
2 );
person3.setAge(
21 );
person3.setName(
" Jack " );
personList.add(person3);

Person person4
= new Person();
person4.setId(
3 );
person4.setAge(
23 );
person4.setName(
" Rose " );
personList.add(person4);
return personList;
}

/*
* 获取年龄等于age参数的Person,因为数据将返还给客户端,所以这时把输出数据转化为JSONArray
*/
public JSONArray GetListByAge(JSONArray jsonList) throws JSONException{
int age = jsonList.getInt( 0 ); // 因为输入参数为一个集合params,所以即使只包括一个参数,也是通过要jsonList的第一个参数来获取的。
List < Person > personList = GetList();
List
< Person > resultList = new ArrayList < Person > ();

for ( int n = 0 ;n < personList.size();n ++ ){
if (personList. get (n).getAge() == age)
resultList.add(personList.
get (n));
}

JSONArray jsonArray
= new JSONArray(resultList);
return jsonArray;
}
}

  然后在Contracts.xml设置绑定:

 
 
< Contracts >
< Contract name ="GetPersonByAge" > //契约名称
< Input >
< Description > 获取Age等于此值的People对象集 </ Description > //文字说明
</ Input >
< Output >
< Package > Manager </ Package > //绑定包
< Class > PersonManager </ Class > //绑定类
< Method > GetListByAge </ Method > //绑定处理方法
</ Output >
</ Contract >
</ Contracts >

  绑定以后,在完成客户端开发的时候就可以进行测试。使用这开发模式的好处在于利用JSON作用数据传输的桥梁,解决不同开发平台之间数据难以同步的问题。使用JSON比XML更容易操作,可以减少传输流量,而且受到各开发语言的支持。使用Contracts.xml在服务器绑定处理方式,使服务器的处理方法与客户端发送的请求实现分离。下面开始介绍一下客户端的开发。

  客户端开发

  客户端的开发的开发相对简单,因为契约是使用   {“ContractName”:“GetPeopleByAge”,“Params”:[23]}    JSON方式进行传送,所以先开发一个MessageEntity实体类来承载契约。

 
 
namespace Model
{
[DataContract]
public class MessageEntity
{
// 契约名称
[DataMember]
public string ContractName
{
get ;
set ;
}

// 注意参数使用集合的方式来传送
[DataMember]
public IList < Object > Params
{
get ;
set ;
}
}
}

  然后开发一个MessageManager信息管理器来管理契约的传送过程,因为Framework4.0里面,未能对JSON数据中集合的转换提供一个简单函数,所以在MessageManager里面使用了一个Newtonsoft.Json工具包,该工具包里面对JSON的操作有着强大支持,可以在http://www.codeplex.com/官方网站下载:

 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Threading;
using Model;
using Newtonsoft.Json;

namespace Common
{
public class MessageManager
{
private static TcpClient _tcpClient;

// 设置tcpClient对象
public static TcpClient TcpClient
{
set { _tcpClient = value; }
}

// 此处只使用静态方法实现数据传送,发送请求后使用Thread.Sleep等待运算结果,这样存在一定风险,也会降低效率
// 在大型的开发当中应该进一步改善,把信息发送与信息接收分开处理
public static object GetMessage(MessageEntity message, Type type)
{
NetworkStream networkStream
= _tcpClient.GetStream();
// 利用DataContractJsonSerializer将MessageEntity对象实现序列化,发送到服务器
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer( typeof (MessageEntity));
lock (networkStream)
{
jsonSerializer.WriteObject(networkStream, message);
networkStream.Flush();
}
Thread.Sleep(
500 );

// 获取回传信息,这里设置接收值1024个字节
// 在实际的开发当中应该使用分批缓存的方式实现数据接收
byte [] messageByte = new byte [ 1024 ];
int n = 0 ;
lock (networkStream)
n
= networkStream.Read(messageByte, 0 , 1024 );
if (n == 0 )
return null ;

// 根据输入的type对象,把二进制信息转化为对应的对象
string jsonMessage = Encoding.ASCII.GetString(messageByte);
// 利用Netonsoft.Json工具集将获取的JSON数据转化对象
object returnValue = JavaScriptConvert.DeserializeObject(jsonMessage, type);
return returnValue;
}
}
}

  下面开发一个GetPersonByAge 契约作为例子:

 
 
using System;
using System.Collections.Generic;
using System.Text;
using Model;
using Common;

namespace DAL
{
public class PersonDAL
{
/// <summary>
/// 建立MessageEntity对象,注意输入额定契约名称及数据参数,获取查询结果
/// </summary>
/// <param name="age"> Person的年龄 </param>
/// <returns> 获取年龄等于此值的Person对象集 </returns>
public IList < Person > GetPersonByAge( int age)
{
// 先建立一个MessageEntity对象,设定其ContractName及参数集合
// 注意ContractName的值必须与服务器端Contracts.xml文件中Contract 项的 name 特性相对应
MessageEntity messageEntity = new MessageEntity();
messageEntity.ContractName
= " GetPersonByAge " ;
messageEntity.Params
= new List < Object > { age };
// 调用MessageManager的GetMessage方法获取计算结果
IList < Person > personList = (List < Person > )MessageManager.GetMessage(messageEntity, typeof (List < Person > ));
return personList;
}
}
}

  PersonDAL类中的GetPersonByAge方法就是把契约封装在MessageEntity当中,再利用MessageManager把契约发送到服务器端获取运行结果,然后把结果转换为JSON,最后利用Netonsoft.Json工具集的JavaScriptConvert类,把JSON转换成Person对象。

  测试

 
  
namespace Model
{
public class Person
{
private int _id;
private string _name;
private int _age;

public int id
{
get { return _id; }
set { _id = value; }
}

public int age
{
get { return _age; }
set { _age = value; }
}

public string name
{
get { return _name; }
set { _name = value; }
}

}
}

  直接调用DAL层

 
  
namespace BLL
{
public class PersonBLL
{
private PersonDAL personDal;

public PersonBLL()
{
personDal
= new PersonDAL();
}

public IList < Person > GetPersonByAge( int age)
{
IList
< Person > personList = personDal.GetPersonByAge(age);
if (personList.Count != 0 )
return personList;
else
return new List < Person > ();
}
}
}

  测试

 
  
class Program
{
private static TcpClient tcpClient = new TcpClient();

static void Main( string [] args)
{
tcpClient.Connect(
" 127.0.0.1 " , 5100 );
MessageManager.TcpClient
= tcpClient;

PersonBLL personBll
= new PersonBLL();
IList
< Person > personList = personBll.GetPersonByAge( 23 );
if (personList.Count != 0 )
Console.WriteLine(personList.Count.ToString());
Console.ReadKey();
}
}

  注意测试是输入的查询条件转换成JSON后是 {“ContractName”:“GetPeopleByAge”,“Params”:[23]},而这种  “ContractName":  "契约名","Params": {参数,参数,...}    传送格式是固定不可改变的。当获取查询结果  "[{\"id\":0,\"age\":23,\"name\":\"Mike\"},{\"id\":3,\"age\":23,\"name\":\"Rose\"}] 后 ,MessageManager将通过Newtonsoft.Json把返还值转换为List<Person>。

  到此处,在下为大家介绍了利用JSON数据实现JAVA与.NET之间TCP/IP相互调用,其实以JSON的方式实现并不是唯一的选择,只是在下想在惯常的用法之上,利用一下这个另类的方法,至于在开发结构上有不够周全的地方敬请各位点评。至于以.NET为服务器,JAVA为客户端的TCP/IP通讯实例与此例子极为相像,在此就不作介绍了。

  原代码 : (由于上传空间有限,未能将JAVA项目的.metadata一并上传,请运行时先建立JAVA Project项目,再加入原代码即可以成功运行)下载

目录
相关文章
|
7天前
|
运维 持续交付 API
从零构建微服务架构:一次深度技术探索之旅####
【10月更文挑战第28天】 本文记录了作者在从零开始构建微服务架构过程中的深刻技术感悟,通过实战案例详细剖析了微服务设计、开发、部署及运维中的关键要点与挑战。文章首先概述了微服务架构的核心理念及其对企业IT架构转型的重要性,随后深入探讨了服务拆分策略、API网关选型、服务间通信协议选择、容器化部署(Docker+Kubernetes)、以及持续集成/持续部署(CI/CD)流程的设计与优化。最后,分享了在高并发场景下的性能调优经验与故障排查心得,旨在为读者提供一套可借鉴的微服务架构实施路径。 ####
42 3
|
2天前
|
Kubernetes Cloud Native 云计算
云原生技术深度解析:重塑企业IT架构的未来####
本文深入探讨了云原生技术的核心理念、关键技术组件及其对企业IT架构转型的深远影响。通过剖析Kubernetes、微服务、容器化等核心技术,本文揭示了云原生如何提升应用的灵活性、可扩展性和可维护性,助力企业在数字化转型中保持领先地位。 ####
|
4天前
|
存储 分布式计算 分布式数据库
风险数据集市整体架构及技术实现
【11月更文挑战第11天】在当今大数据时代,风险数据集市作为金融机构的核心基础设施之一,扮演着至关重要的角色。它不仅为银行、保险等金融机构提供了全面、准确的风险数据支持,还帮助这些机构实现了风险管理的精细化和智能化。本文将深入探讨一种基于大数据Lambda架构设计的风险数据集市整体架构,并详细介绍其底层实现原理及实现方式。
17 3
|
5天前
|
JSON 前端开发 JavaScript
java-ajax技术详解!!!
本文介绍了Ajax技术及其工作原理,包括其核心XMLHttpRequest对象的属性和方法。Ajax通过异步通信技术,实现在不重新加载整个页面的情况下更新部分网页内容。文章还详细描述了使用原生JavaScript实现Ajax的基本步骤,以及利用jQuery简化Ajax操作的方法。最后,介绍了JSON作为轻量级数据交换格式在Ajax应用中的使用,包括Java中JSON与对象的相互转换。
13 1
|
7天前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
10天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
25 3
|
10天前
|
Java 网络安全 Maven
Exception in thread "main" java.lang.NoSuchMethodError: okhttp3.OkHttpClient$Builder.sslSocketFactory(Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder; 问题处理
【10月更文挑战第26天】Exception in thread "main" java.lang.NoSuchMethodError: okhttp3.OkHttpClient$Builder.sslSocketFactory(Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder; 问题处理
32 2
|
10天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
14 1
|
10天前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
25 1
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
38 7
下一篇
无影云桌面