apache thrift 入门(一)
1.简介
Apache Thrift软件框架,是用来开发可扩展的跨语言的软件服务。通过软件堆栈和代码生成引擎相结合的方式来构建服务,使C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml 、Delphi 等语言之间的工作变得高效且无缝。
以上是官网的简介,首先Thrift 是一种服务之间RPC(Remote Procedure Call)协议通信,也就是远程调用。其次,它提供一种代码生成引擎,可以根据模板来生成不同语言的接口代码,这个代码文件里面就包括包括和服务端之间通讯的所有代码,我们就可以不写这些底层的代码啦。
生成后的代码长这样:
1 /** 2 * Autogenerated by Thrift Compiler (0.11.0) 3 * 4 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 * @generated 6 */ 7 package com.thrift.demo; 8 9 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"}) 10 @javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.11.0)", date = "2019-06-13") 11 public class HelloWorldService { 12 13 public interface Iface { 14 15 public java.lang.String sayHello(java.lang.String name) throws org.apache.thrift.TException; 16 17 } 18 19 public interface AsyncIface { 20 21 public void sayHello(java.lang.String name, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException; 22 23 } 24 25 public static class Client extends org.apache.thrift.TServiceClient implements Iface { 26 public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> { 27 public Factory() {} 28 public Client getClient(org.apache.thrift.protocol.TProtocol prot) { 29 return new Client(prot); 30 } 31 public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) { 32 return new Client(iprot, oprot); 33 } 34 } 35 36 public Client(org.apache.thrift.protocol.TProtocol prot) 37 { 38 super(prot, prot); 39 } 40 41 public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) { 42 super(iprot, oprot); 43 } 44 45 public java.lang.String sayHello(java.lang.String name) throws org.apache.thrift.TException 46 { 47 send_sayHello(name); 48 return recv_sayHello(); 49 } 50 51 public void send_sayHello(java.lang.String name) throws org.apache.thrift.TException 52 { 53 sayHello_args args = new sayHello_args(); 54 args.setName(name); 55 sendBase("sayHello", args); 56 } 57 58 public java.lang.String recv_sayHello() throws org.apache.thrift.TException 59 { 60 sayHello_result result = new sayHello_result(); 61 receiveBase(result, "sayHello"); 62 if (result.isSetSuccess()) { 63 return result.success; 64 } 65 throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "sayHello failed: unknown result"); 66 } 67 68 } 69 public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface { 70 public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> { 71 private org.apache.thrift.async.TAsyncClientManager clientManager; 72 private org.apache.thrift.protocol.TProtocolFactory protocolFactory; 73 public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) { 74 this.clientManager = clientManager; 75 this.protocolFactory = protocolFactory; 76 } 77 public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) { 78 return new AsyncClient(protocolFactory, clientManager, transport); 79 } 80 } 81 82 public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) { 83 super(protocolFactory, clientManager, transport); 84 } 85 86 public void sayHello(java.lang.String name, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException { 87 checkReady(); 88 sayHello_call method_call = new sayHello_call(name, resultHandler, this, ___protocolFactory, ___transport); 89 this.___currentMethod = method_call; 90 ___manager.call(method_call); 91 } 92 93 public static class sayHello_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> { 94 private java.lang.String name; 95 public sayHello_call(java.lang.String name, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException { 96 super(client, protocolFactory, transport, resultHandler, false); 97 this.name = name; 98 } 99 100 public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException { 101 prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("sayHello", org.apache.thrift.protocol.TMessageType.CALL, 0)); 102 sayHello_args args = new sayHello_args(); 103 args.setName(name); 104 args.write(prot); 105 prot.writeMessageEnd(); 106 } 107 108 public java.lang.String getResult() throws org.apache.thrift.TException { 109 if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) { 110 throw new java.lang.IllegalStateException("Method call not finished!"); 111 } 112 org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array()); 113 org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); 114 return (new Client(prot)).recv_sayHello(); 115 } 116 } 117 118 } 119 120 public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor { 121 private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName()); 122 public Processor(I iface) { 123 super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>())); 124 } 125 126 protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) { 127 super(iface, getProcessMap(processMap)); 128 } 129 130 private static <I extends Iface> java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) { 131 processMap.put("sayHello", new sayHello()); 132 return processMap; 133 } 134 135 public static class sayHello<I extends Iface> extends org.apache.thrift.ProcessFunction<I, sayHello_args> { 136 public sayHello() { 137 super("sayHello"); 138 } 139 140 public sayHello_args getEmptyArgsInstance() { 141 return new sayHello_args(); 142 } 143 144 protected boolean isOneway() { 145 return false; 146 } 147 148 @Override 149 protected boolean handleRuntimeExceptions() { 150 return false; 151 } 152 153 public sayHello_result getResult(I iface, sayHello_args args) throws org.apache.thrift.TException { 154 sayHello_result result = new sayHello_result(); 155 result.success = iface.sayHello(args.name); 156 return result; 157 } 158 } 159 160 } 161 162 public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> { 163 private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName()); 164 public AsyncProcessor(I iface) { 165 super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>())); 166 } 167 168 protected AsyncProcessor(I iface, java.util.Map<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>> processMap) { 169 super(iface, getProcessMap(processMap)); 170 } 171 172 private static <I extends AsyncIface> java.util.Map<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>> processMap) { 173 processMap.put("sayHello", new sayHello()); 174 return processMap; 175 } 176 177 public static class sayHello<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, sayHello_args, java.lang.String> { 178 public sayHello() { 179 super("sayHello"); 180 } 181 182 public sayHello_args getEmptyArgsInstance() { 183 return new sayHello_args(); 184 } 185 186 public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) { 187 final org.apache.thrift.AsyncProcessFunction fcall = this; 188 return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 189 public void onComplete(java.lang.String o) { 190 sayHello_result result = new sayHello_result(); 191 result.success = o; 192 try { 193 fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid); 194 } catch (org.apache.thrift.transport.TTransportException e) { 195 _LOGGER.error("TTransportException writing to internal frame buffer", e); 196 fb.close(); 197 } catch (java.lang.Exception e) { 198 _LOGGER.error("Exception writing to internal frame buffer", e); 199 onError(e); 200 } 201 } 202 public void onError(java.lang.Exception e) { 203 byte msgType = org.apache.thrift.protocol.TMessageType.REPLY; 204 org.apache.thrift.TSerializable msg; 205 sayHello_result result = new sayHello_result(); 206 if (e instanceof org.apache.thrift.transport.TTransportException) { 207 _LOGGER.error("TTransportException inside handler", e); 208 fb.close(); 209 return; 210 } else if (e instanceof org.apache.thrift.TApplicationException) { 211 _LOGGER.error("TApplicationException inside handler", e); 212 msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION; 213 msg = (org.apache.thrift.TApplicationException)e; 214 } else { 215 _LOGGER.error("Exception inside handler", e); 216 msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION; 217 msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage()); 218 } 219 try { 220 fcall.sendResponse(fb,msg,msgType,seqid); 221 } catch (java.lang.Exception ex) { 222 _LOGGER.error("Exception writing to internal frame buffer", ex); 223 fb.close(); 224 } 225 } 226 }; 227 } 228 229 protected boolean isOneway() { 230 return false; 231 } 232 233 public void start(I iface, sayHello_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException { 234 iface.sayHello(args.name,resultHandler); 235 } 236 } 237 238 } 239 240 public static class sayHello_args implements org.apache.thrift.TBase<sayHello_args, sayHello_args._Fields>, java.io.Serializable, Cloneable, Comparable<sayHello_args> { 241 private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("sayHello_args"); 242 243 private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1); 244 245 private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sayHello_argsStandardSchemeFactory(); 246 private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sayHello_argsTupleSchemeFactory(); 247 248 public java.lang.String name; // required 249 250 /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 251 public enum _Fields implements org.apache.thrift.TFieldIdEnum { 252 NAME((short)1, "name"); 253 254 private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>(); 255 256 static { 257 for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 258 byName.put(field.getFieldName(), field); 259 } 260 } 261 262 /** 263 * Find the _Fields constant that matches fieldId, or null if its not found. 264 */ 265 public static _Fields findByThriftId(int fieldId) { 266 switch(fieldId) { 267 case 1: // NAME 268 return NAME; 269 default: 270 return null; 271 } 272 } 273 274 /** 275 * Find the _Fields constant that matches fieldId, throwing an exception 276 * if it is not found. 277 */ 278 public static _Fields findByThriftIdOrThrow(int fieldId) { 279 _Fields fields = findByThriftId(fieldId); 280 if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 281 return fields; 282 } 283 284 /** 285 * Find the _Fields constant that matches name, or null if its not found. 286 */ 287 public static _Fields findByName(java.lang.String name) { 288 return byName.get(name); 289 } 290 291 private final short _thriftId; 292 private final java.lang.String _fieldName; 293 294 _Fields(short thriftId, java.lang.String fieldName) { 295 _thriftId = thriftId; 296 _fieldName = fieldName; 297 } 298 299 public short getThriftFieldId() { 300 return _thriftId; 301 } 302 303 public java.lang.String getFieldName() { 304 return _fieldName; 305 } 306 } 307 308 // isset id assignments 309 public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 310 static { 311 java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 312 tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT, 313 new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 314 metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 315 org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_args.class, metaDataMap); 316 } 317 318 public sayHello_args() { 319 } 320 321 public sayHello_args( 322 java.lang.String name) 323 { 324 this(); 325 this.name = name; 326 } 327 328 /** 329 * Performs a deep copy on <i>other</i>. 330 */ 331 public sayHello_args(sayHello_args other) { 332 if (other.isSetName()) { 333 this.name = other.name; 334 } 335 } 336 337 public sayHello_args deepCopy() { 338 return new sayHello_args(this); 339 } 340 341 @Override 342 public void clear() { 343 this.name = null; 344 } 345 346 public java.lang.String getName() { 347 return this.name; 348 } 349 350 public sayHello_args setName(java.lang.String name) { 351 this.name = name; 352 return this; 353 } 354 355 public void unsetName() { 356 this.name = null; 357 } 358 359 /** Returns true if field name is set (has been assigned a value) and false otherwise */ 360 public boolean isSetName() { 361 return this.name != null; 362 } 363 364 public void setNameIsSet(boolean value) { 365 if (!value) { 366 this.name = null; 367 } 368 } 369 370 public void setFieldValue(_Fields field, java.lang.Object value) { 371 switch (field) { 372 case NAME: 373 if (value == null) { 374 unsetName(); 375 } else { 376 setName((java.lang.String)value); 377 } 378 break; 379 380 } 381 } 382 383 public java.lang.Object getFieldValue(_Fields field) { 384 switch (field) { 385 case NAME: 386 return getName(); 387 388 } 389 throw new java.lang.IllegalStateException(); 390 } 391 392 /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 393 public boolean isSet(_Fields field) { 394 if (field == null) { 395 throw new java.lang.IllegalArgumentException(); 396 } 397 398 switch (field) { 399 case NAME: 400 return isSetName(); 401 } 402 throw new java.lang.IllegalStateException(); 403 } 404 405 @Override 406 public boolean equals(java.lang.Object that) { 407 if (that == null) 408 return false; 409 if (that instanceof sayHello_args) 410 return this.equals((sayHello_args)that); 411 return false; 412 } 413 414 public boolean equals(sayHello_args that) { 415 if (that == null) 416 return false; 417 if (this == that) 418 return true; 419 420 boolean this_present_name = true && this.isSetName(); 421 boolean that_present_name = true && that.isSetName(); 422 if (this_present_name || that_present_name) { 423 if (!(this_present_name && that_present_name)) 424 return false; 425 if (!this.name.equals(that.name)) 426 return false; 427 } 428 429 return true; 430 } 431 432 @Override 433 public int hashCode() { 434 int hashCode = 1; 435 436 hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287); 437 if (isSetName()) 438 hashCode = hashCode * 8191 + name.hashCode(); 439 440 return hashCode; 441 } 442 443 @Override 444 public int compareTo(sayHello_args other) { 445 if (!getClass().equals(other.getClass())) { 446 return getClass().getName().compareTo(other.getClass().getName()); 447 } 448 449 int lastComparison = 0; 450 451 lastComparison = java.lang.Boolean.valueOf(isSetName()).compareTo(other.isSetName()); 452 if (lastComparison != 0) { 453 return lastComparison; 454 } 455 if (isSetName()) { 456 lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name); 457 if (lastComparison != 0) { 458 return lastComparison; 459 } 460 } 461 return 0; 462 } 463 464 public _Fields fieldForId(int fieldId) { 465 return _Fields.findByThriftId(fieldId); 466 } 467 468 public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 469 scheme(iprot).read(iprot, this); 470 } 471 472 public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 473 scheme(oprot).write(oprot, this); 474 } 475 476 @Override 477 public java.lang.String toString() { 478 java.lang.StringBuilder sb = new java.lang.StringBuilder("sayHello_args("); 479 boolean first = true; 480 481 sb.append("name:"); 482 if (this.name == null) { 483 sb.append("null"); 484 } else { 485 sb.append(this.name); 486 } 487 first = false; 488 sb.append(")"); 489 return sb.toString(); 490 } 491 492 public void validate() throws org.apache.thrift.TException { 493 // check for required fields 494 // check for sub-struct validity 495 } 496 497 private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 498 try { 499 write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 500 } catch (org.apache.thrift.TException te) { 501 throw new java.io.IOException(te); 502 } 503 } 504 505 private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 506 try { 507 read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 508 } catch (org.apache.thrift.TException te) { 509 throw new java.io.IOException(te); 510 } 511 } 512 513 private static class sayHello_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 514 public sayHello_argsStandardScheme getScheme() { 515 return new sayHello_argsStandardScheme(); 516 } 517 } 518 519 private static class sayHello_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<sayHello_args> { 520 521 public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_args struct) throws org.apache.thrift.TException { 522 org.apache.thrift.protocol.TField schemeField; 523 iprot.readStructBegin(); 524 while (true) 525 { 526 schemeField = iprot.readFieldBegin(); 527 if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 528 break; 529 } 530 switch (schemeField.id) { 531 case 1: // NAME 532 if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 533 struct.name = iprot.readString(); 534 struct.setNameIsSet(true); 535 } else { 536 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 537 } 538 break; 539 default: 540 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 541 } 542 iprot.readFieldEnd(); 543 } 544 iprot.readStructEnd(); 545 546 // check for required fields of primitive type, which can't be checked in the validate method 547 struct.validate(); 548 } 549 550 public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_args struct) throws org.apache.thrift.TException { 551 struct.validate(); 552 553 oprot.writeStructBegin(STRUCT_DESC); 554 if (struct.name != null) { 555 oprot.writeFieldBegin(NAME_FIELD_DESC); 556 oprot.writeString(struct.name); 557 oprot.writeFieldEnd(); 558 } 559 oprot.writeFieldStop(); 560 oprot.writeStructEnd(); 561 } 562 563 } 564 565 private static class sayHello_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 566 public sayHello_argsTupleScheme getScheme() { 567 return new sayHello_argsTupleScheme(); 568 } 569 } 570 571 private static class sayHello_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<sayHello_args> { 572 573 @Override 574 public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException { 575 org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 576 java.util.BitSet optionals = new java.util.BitSet(); 577 if (struct.isSetName()) { 578 optionals.set(0); 579 } 580 oprot.writeBitSet(optionals, 1); 581 if (struct.isSetName()) { 582 oprot.writeString(struct.name); 583 } 584 } 585 586 @Override 587 public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException { 588 org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 589 java.util.BitSet incoming = iprot.readBitSet(1); 590 if (incoming.get(0)) { 591 struct.name = iprot.readString(); 592 struct.setNameIsSet(true); 593 } 594 } 595 } 596 597 private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) { 598 return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 599 } 600 } 601 602 public static class sayHello_result implements org.apache.thrift.TBase<sayHello_result, sayHello_result._Fields>, java.io.Serializable, Cloneable, Comparable<sayHello_result> { 603 private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("sayHello_result"); 604 605 private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0); 606 607 private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new sayHello_resultStandardSchemeFactory(); 608 private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new sayHello_resultTupleSchemeFactory(); 609 610 public java.lang.String success; // required 611 612 /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ 613 public enum _Fields implements org.apache.thrift.TFieldIdEnum { 614 SUCCESS((short)0, "success"); 615 616 private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>(); 617 618 static { 619 for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) { 620 byName.put(field.getFieldName(), field); 621 } 622 } 623 624 /** 625 * Find the _Fields constant that matches fieldId, or null if its not found. 626 */ 627 public static _Fields findByThriftId(int fieldId) { 628 switch(fieldId) { 629 case 0: // SUCCESS 630 return SUCCESS; 631 default: 632 return null; 633 } 634 } 635 636 /** 637 * Find the _Fields constant that matches fieldId, throwing an exception 638 * if it is not found. 639 */ 640 public static _Fields findByThriftIdOrThrow(int fieldId) { 641 _Fields fields = findByThriftId(fieldId); 642 if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!"); 643 return fields; 644 } 645 646 /** 647 * Find the _Fields constant that matches name, or null if its not found. 648 */ 649 public static _Fields findByName(java.lang.String name) { 650 return byName.get(name); 651 } 652 653 private final short _thriftId; 654 private final java.lang.String _fieldName; 655 656 _Fields(short thriftId, java.lang.String fieldName) { 657 _thriftId = thriftId; 658 _fieldName = fieldName; 659 } 660 661 public short getThriftFieldId() { 662 return _thriftId; 663 } 664 665 public java.lang.String getFieldName() { 666 return _fieldName; 667 } 668 } 669 670 // isset id assignments 671 public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap; 672 static { 673 java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class); 674 tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 675 new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))); 676 metaDataMap = java.util.Collections.unmodifiableMap(tmpMap); 677 org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_result.class, metaDataMap); 678 } 679 680 public sayHello_result() { 681 } 682 683 public sayHello_result( 684 java.lang.String success) 685 { 686 this(); 687 this.success = success; 688 } 689 690 /** 691 * Performs a deep copy on <i>other</i>. 692 */ 693 public sayHello_result(sayHello_result other) { 694 if (other.isSetSuccess()) { 695 this.success = other.success; 696 } 697 } 698 699 public sayHello_result deepCopy() { 700 return new sayHello_result(this); 701 } 702 703 @Override 704 public void clear() { 705 this.success = null; 706 } 707 708 public java.lang.String getSuccess() { 709 return this.success; 710 } 711 712 public sayHello_result setSuccess(java.lang.String success) { 713 this.success = success; 714 return this; 715 } 716 717 public void unsetSuccess() { 718 this.success = null; 719 } 720 721 /** Returns true if field success is set (has been assigned a value) and false otherwise */ 722 public boolean isSetSuccess() { 723 return this.success != null; 724 } 725 726 public void setSuccessIsSet(boolean value) { 727 if (!value) { 728 this.success = null; 729 } 730 } 731 732 public void setFieldValue(_Fields field, java.lang.Object value) { 733 switch (field) { 734 case SUCCESS: 735 if (value == null) { 736 unsetSuccess(); 737 } else { 738 setSuccess((java.lang.String)value); 739 } 740 break; 741 742 } 743 } 744 745 public java.lang.Object getFieldValue(_Fields field) { 746 switch (field) { 747 case SUCCESS: 748 return getSuccess(); 749 750 } 751 throw new java.lang.IllegalStateException(); 752 } 753 754 /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */ 755 public boolean isSet(_Fields field) { 756 if (field == null) { 757 throw new java.lang.IllegalArgumentException(); 758 } 759 760 switch (field) { 761 case SUCCESS: 762 return isSetSuccess(); 763 } 764 throw new java.lang.IllegalStateException(); 765 } 766 767 @Override 768 public boolean equals(java.lang.Object that) { 769 if (that == null) 770 return false; 771 if (that instanceof sayHello_result) 772 return this.equals((sayHello_result)that); 773 return false; 774 } 775 776 public boolean equals(sayHello_result that) { 777 if (that == null) 778 return false; 779 if (this == that) 780 return true; 781 782 boolean this_present_success = true && this.isSetSuccess(); 783 boolean that_present_success = true && that.isSetSuccess(); 784 if (this_present_success || that_present_success) { 785 if (!(this_present_success && that_present_success)) 786 return false; 787 if (!this.success.equals(that.success)) 788 return false; 789 } 790 791 return true; 792 } 793 794 @Override 795 public int hashCode() { 796 int hashCode = 1; 797 798 hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287); 799 if (isSetSuccess()) 800 hashCode = hashCode * 8191 + success.hashCode(); 801 802 return hashCode; 803 } 804 805 @Override 806 public int compareTo(sayHello_result other) { 807 if (!getClass().equals(other.getClass())) { 808 return getClass().getName().compareTo(other.getClass().getName()); 809 } 810 811 int lastComparison = 0; 812 813 lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess()); 814 if (lastComparison != 0) { 815 return lastComparison; 816 } 817 if (isSetSuccess()) { 818 lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success); 819 if (lastComparison != 0) { 820 return lastComparison; 821 } 822 } 823 return 0; 824 } 825 826 public _Fields fieldForId(int fieldId) { 827 return _Fields.findByThriftId(fieldId); 828 } 829 830 public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException { 831 scheme(iprot).read(iprot, this); 832 } 833 834 public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException { 835 scheme(oprot).write(oprot, this); 836 } 837 838 @Override 839 public java.lang.String toString() { 840 java.lang.StringBuilder sb = new java.lang.StringBuilder("sayHello_result("); 841 boolean first = true; 842 843 sb.append("success:"); 844 if (this.success == null) { 845 sb.append("null"); 846 } else { 847 sb.append(this.success); 848 } 849 first = false; 850 sb.append(")"); 851 return sb.toString(); 852 } 853 854 public void validate() throws org.apache.thrift.TException { 855 // check for required fields 856 // check for sub-struct validity 857 } 858 859 private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 860 try { 861 write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out))); 862 } catch (org.apache.thrift.TException te) { 863 throw new java.io.IOException(te); 864 } 865 } 866 867 private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { 868 try { 869 read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in))); 870 } catch (org.apache.thrift.TException te) { 871 throw new java.io.IOException(te); 872 } 873 } 874 875 private static class sayHello_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 876 public sayHello_resultStandardScheme getScheme() { 877 return new sayHello_resultStandardScheme(); 878 } 879 } 880 881 private static class sayHello_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<sayHello_result> { 882 883 public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_result struct) throws org.apache.thrift.TException { 884 org.apache.thrift.protocol.TField schemeField; 885 iprot.readStructBegin(); 886 while (true) 887 { 888 schemeField = iprot.readFieldBegin(); 889 if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 890 break; 891 } 892 switch (schemeField.id) { 893 case 0: // SUCCESS 894 if (schemeField.type == org.apache.thrift.protocol.TType.STRING) { 895 struct.success = iprot.readString(); 896 struct.setSuccessIsSet(true); 897 } else { 898 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 899 } 900 break; 901 default: 902 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type); 903 } 904 iprot.readFieldEnd(); 905 } 906 iprot.readStructEnd(); 907 908 // check for required fields of primitive type, which can't be checked in the validate method 909 struct.validate(); 910 } 911 912 public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_result struct) throws org.apache.thrift.TException { 913 struct.validate(); 914 915 oprot.writeStructBegin(STRUCT_DESC); 916 if (struct.success != null) { 917 oprot.writeFieldBegin(SUCCESS_FIELD_DESC); 918 oprot.writeString(struct.success); 919 oprot.writeFieldEnd(); 920 } 921 oprot.writeFieldStop(); 922 oprot.writeStructEnd(); 923 } 924 925 } 926 927 private static class sayHello_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory { 928 public sayHello_resultTupleScheme getScheme() { 929 return new sayHello_resultTupleScheme(); 930 } 931 } 932 933 private static class sayHello_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<sayHello_result> { 934 935 @Override 936 public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException { 937 org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 938 java.util.BitSet optionals = new java.util.BitSet(); 939 if (struct.isSetSuccess()) { 940 optionals.set(0); 941 } 942 oprot.writeBitSet(optionals, 1); 943 if (struct.isSetSuccess()) { 944 oprot.writeString(struct.success); 945 } 946 } 947 948 @Override 949 public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException { 950 org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot; 951 java.util.BitSet incoming = iprot.readBitSet(1); 952 if (incoming.get(0)) { 953 struct.success = iprot.readString(); 954 struct.setSuccessIsSet(true); 955 } 956 } 957 } 958 959 private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) { 960 return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme(); 961 } 962 } 963 964 }
这里面只要我们重写face 就可以了。
2.IDL(Interface Description Language)
Apache Thrift 需要一个定义数据类型和服务接口的简单定义文件作为模板提供给代码生成引擎用来生成生成客户端代码和服务端代码,并以此实现客户端与服务端之间的跨语言的无缝通讯。我们就不用编写大量重复的模块化代码来序列化和传输对象,实现远程接口调用了,我们可以直接专注于业务逻辑。
Thrift生成引擎需要定义文件,这个文件的语法,我们称之为 IDL(Interface Description Language)接口描述语言。我也不知道为啥叫这个 = 。=
官网文件:
1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 # Thrift Tutorial 21 # Mark Slee (mcslee@facebook.com) 22 # 23 # This file aims to teach you how to use Thrift, in a .thrift file. Neato. The 24 # first thing to notice is that .thrift files support standard shell comments. 25 # This lets you make your thrift file executable and include your Thrift build 26 # step on the top line. And you can place comments like this anywhere you like. 27 # 28 # Before running this file, you will need to have installed the thrift compiler 29 # into /usr/local/bin. 30 31 /** 32 * The first thing to know about are types. The available types in Thrift are: 33 * 34 * bool Boolean, one byte 35 * i8 (byte) Signed 8-bit integer 36 * i16 Signed 16-bit integer 37 * i32 Signed 32-bit integer 38 * i64 Signed 64-bit integer 39 * double 64-bit floating point value 40 * string String 41 * binary Blob (byte array) 42 * map<t1,t2> Map from one type to another 43 * list<t1> Ordered list of one type 44 * set<t1> Set of unique elements of one type 45 * 46 * Did you also notice that Thrift supports C style comments? 47 */ 48 49 // Just in case you were wondering... yes. We support simple C comments too. 50 51 /** 52 * Thrift files can reference other Thrift files to include common struct 53 * and service definitions. These are found using the current path, or by 54 * searching relative to any paths specified with the -I compiler flag. 55 * 56 * Included objects are accessed using the name of the .thrift file as a 57 * prefix. i.e. shared.SharedObject 58 */ 59 include "shared.thrift" 60 61 /** 62 * Thrift files can namespace, package, or prefix their output in various 63 * target languages. 64 */ 65 66 namespace cl tutorial 67 namespace cpp tutorial 68 namespace d tutorial 69 namespace dart tutorial 70 namespace java tutorial 71 namespace php tutorial 72 namespace perl tutorial 73 namespace haxe tutorial 74 namespace netcore tutorial 75 namespace netstd tutorial 76 77 /** 78 * Thrift lets you do typedefs to get pretty names for your types. Standard 79 * C style here. 80 */ 81 typedef i32 MyInteger 82 83 /** 84 * Thrift also lets you define constants for use across languages. Complex 85 * types and structs are specified using JSON notation. 86 */ 87 const i32 INT32CONSTANT = 9853 88 const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} 89 90 /** 91 * You can define enums, which are just 32 bit integers. Values are optional 92 * and start at 1 if not supplied, C style again. 93 */ 94 enum Operation { 95 ADD = 1, 96 SUBTRACT = 2, 97 MULTIPLY = 3, 98 DIVIDE = 4 99 } 100 101 /** 102 * Structs are the basic complex data structures. They are comprised of fields 103 * which each have an integer identifier, a type, a symbolic name, and an 104 * optional default value. 105 * 106 * Fields can be declared "optional", which ensures they will not be included 107 * in the serialized output if they aren't set. Note that this requires some 108 * manual management in some languages. 109 */ 110 struct Work { 111 1: i32 num1 = 0, 112 2: i32 num2, 113 3: Operation op, 114 4: optional string comment, 115 } 116 117 /** 118 * Structs can also be exceptions, if they are nasty. 119 */ 120 exception InvalidOperation { 121 1: i32 whatOp, 122 2: string why 123 } 124 125 /** 126 * Ahh, now onto the cool part, defining a service. Services just need a name 127 * and can optionally inherit from another service using the extends keyword. 128 */ 129 service Calculator extends shared.SharedService { 130 131 /** 132 * A method definition looks like C code. It has a return type, arguments, 133 * and optionally a list of exceptions that it may throw. Note that argument 134 * lists and exception lists are specified using the exact same syntax as 135 * field lists in struct or exception definitions. 136 */ 137 138 void ping(), 139 140 i32 add(1:i32 num1, 2:i32 num2), 141 142 i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), 143 144 /** 145 * This method has a oneway modifier. That means the client only makes 146 * a request and does not listen for any response at all. Oneway methods 147 * must be void. 148 */ 149 oneway void zip() 150 151 } 152 153 /** 154 * That just about covers the basics. Take a look in the test/ folder for more 155 * detailed examples. After you run this file, your generated code shows up 156 * in folders with names gen-<language>. The generated code isn't too scary 157 * to look at. It even has pretty indentation. 158 */
首先我们来注意一下数据类型:
1 * bool Boolean, one byte 2 * i8 (byte) Signed 8-bit integer 3 * i16 Signed 16-bit integer 4 * i32 Signed 32-bit integer 5 * i64 Signed 64-bit integer 6 * double 64-bit floating point value 7 * string String 8 * binary Blob (byte array) 9 * map<t1,t2> Map from one type to another 10 * list<t1> Ordered list of one type 11 * set<t1> Set of unique elements of one type
bool: 布尔值,true 或 false,对应 Java 的 Boolean
i8(byte): 8 位有符号整数,对应 Java 的 byte
i16:16 位有符号整数,对应 Java 的 short
i32:32 位有符号整数,对应 Java 的 int
i64:64 位有符号整数,对应 Java 的 long
double:64 位浮点数,对应 Java 的 double
string:utf-8编码的字符串,对应 Java 的 String
binary:字节数组,对应Java的Array[byte]
map、list、set不用多说。
这种定义方式和C语言很相似,同时thrift定义文件还支持C语言的注释方式
以上是基本的类型。
thrift的枚举类型类似于java
enum Operation { ADD = 1, SUBTRACT = 2, MULTIPLY = 3, DIVIDE = 4 }
thrift自定义结构体和C语言一样是struct,也就是java中定义的DTO
struct Work { 1: i32 num1 = 0, 2: i32 num2, 3: Operation op, 4: optional string comment, }
thrift定义的方法可能会抛出异常,异常也是struct。这很合理 = ^_^=
exception InvalidOperation { 1: i32 whatOp, 2: string why }
thrift 还支持 C语言的typedef 关键字进行类型定义,这个是用来自定义类型,你可以这样
typedef i32 MyInteger
这样你就可以用MyInteger 来代替 int类型了,好像是个没用的例子=。=
简单说了一下基本类型,接下来是限定修饰符:
常量修饰符:const
需要注意的是当声明的常量是复杂类型时,需要使用json格式
const i32 INT32CONSTANT = 9853 const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
啊哈,接下来到了最酷的环节,定义服务。定义服务需要一个名字,也可以选择继承某个服务。继承服务的话,需要 include "shared.thrift"。类似于导包
service Calculator extends shared.SharedService { /** * A method definition looks like C code. It has a return type, arguments, * and optionally a list of exceptions that it may throw. Note that argument * lists and exception lists are specified using the exact same syntax as * field lists in struct or exception definitions. */ void ping(), i32 add(1:i32 num1, 2:i32 num2), i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), /** * This method has a oneway modifier. That means the client only makes * a request and does not listen for any response at all. Oneway methods * must be void. */ oneway void zip() }
以上就是所谓的 Interface Description Language 接口定义语言,这个名词到底哪来的 =_= !