Web3js的使用说明 web3安装与添加
- 安装npm管理工具
- 引入web3到工程
npm init
npm install web3@0.20.1 # 安装0.20.1版本的web3
- 创建web3实例
var Web3 = require("web3")
var web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.1.114:8989"))
- 启动geth的私链节点
geth --datadir data1 --networkid 123 --rpc --rpcaddr 192.168.1.114 --rpcport 8989 --port 3000 --dev console
- 查看node中是否成功连接到对应的私链节点
> web3.isConnected()
true
大数处理
由于在js中不能正确的处理BigNumber,所以需要引入web3.js依赖的大数处理的库。
//在js中若输入大数,则会表示为科学计数法的形式,忽略掉后面的位数。造成错误
> 101010100324325345346456456456456456456
1.0101010032432535e+38//引入大数处理的库
> var BigNumber = require("bignumber.js/")
> var balance = new BigNumber("131242344353464564564574574567456")
> balance
//s符号位 1=>正数,-1=>负数;e:科学计数法的指数的位数;c:具体的数字
BigNumber { s: 1, e: 32, c: [ 13124, 23443534645645, 64574574567456 ] }
但是20位以上的浮点数会出错,推荐使用wei作为单位,再向用户展示的时候再将wei转换为其他单位可以避免此类错误
//使用超过20位的小数,会忽略后面的值
> var balance = new BigNumber('13124.234435346456466666457455567456');
> balance
BigNumber {
s: 1,
e: 4,
c: [ 13124, 23443534645646, 66664574555674, 56000000000000 ]
}
> balance.toString(10)
'13124.23443534645646666646'
基本信息查询
- 查看web3版本
> web3.version.api
'0.20.1'
- 查看web3连接的节点版本
//同步查询
> web3.version.node
'Geth/v1.8.17-stable/linux-amd64/go1.9.7'
//异步查询
> web3.version.getNode(function(err,res) {console.log(res)})
undefined
> Geth/v1.8.17-stable/linux-amd64/go1.9.7
- 网络状态查询
//查看节点连接情况
> web3.isConnected()
true
//查看当前连接的peer节点
> web3.net.peerCount
0
- 获取network id
> web3.version.network
'123'
- provider
//查看当前设置的provider
> web3.currentProvider
HttpProvider {
host: 'http://192.168.1.114:8989',
timeout: 0,
user: undefined,
password: undefined
}//修改provider
> web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"))
undefined
> web3.currentProvider
HttpProvider {
host: 'http://localhost:8545',
timeout: 0,
user: undefined,
password: undefined
}
web3通用工具方法
- 以太单位转换
//将wei转换为其他单位
> web3.fromWei("12371221","ether")
'0.000000000012371221'
//将其他单位转换成wei
> web3.toWei("23","ether")
'23000000000000000000'
- 数据类型转换
//16进制转为10进制,参数类型String
> web3.toDecimal("0x68")
104//数字转为16进制,参数类型String/Number
> web3.fromDecimal(233)
'0xe9'//将任意类型转换为16进制
//Number => Hex
> web3.toHex(233)
'0xe9'
//BigNumber => Hex
> var bignumber = new BigNumber('12345678901234567890');
undefined
> bignumber
BigNumber { s: 1, e: 19, c: [ 123456, 78901234567890 ] }
> web3.toHex(bignumber)
'0xab54a98ceb1f0ad2'//将数字或16进制字符串转换为BigNumber
> web3.toBigNumber('12718838912120101')
BigNumber { s: 1, e: 16, c: [ 127, 18838912120101 ] }
账户相关操作 web3.eth
- 查看挖矿成功奖励的地址
> web3.eth.coinbase
'0x613d104e6d80ce5a06e7987d39bbd4ee0ccd7656'
- 账户查询
> web3.eth.accounts
[
'0x613d104e6d80ce5a06e7987d39bbd4ee0ccd7656',
'0x9f0316428ea5231b7116840df16ae0a768078ffd',
'0xf0a545c9bd6dbb358990b9bded9086d4bcbccbc3'
]
区块相关操作 web3.eth
- 区块高度查询
> web3.eth.blockNumber
10
- 查询对应块号或哈希值锁对应的区块信息
//同步
> web3.eth.getBlock(9)
{
difficulty: BigNumber { s: 1, e: 0, c: [ 2 ] },
extraData: '0xd783010811846765746887676f312e392e37856c696e757800000000000000004a14e4a438d226bdb21674de94d54628d4e7b2018cc8aa72f353c22aa57721152e558c24e5b365e484fbc3cc3e66025fcbdf4464954c9055476e2ab40c383f1500',
gasLimit: 6338608,
gasUsed: 97782,
hash: '0x7aa8a046b41db5caaf64ab527dcfdd283deb41e9a9ef7901b07ea8def687a9fe',
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
miner: '0x0000000000000000000000000000000000000000',
mixHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
nonce: '0x0000000000000000',
number: 9,
parentHash: '0x0c7a2356c3b6b6ee1433046486bfb5f63a2f19208f9549889907fd12a1f34ba4',
receiptsRoot: '0x50ff7c4ac1e71c5c0f0c8e5e006872ff4e4a3ca9fc752ee220414fb023d5c890',
sha3Uncles: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347',
size: 890,
stateRoot: '0x25b55bbcaf1b57c88c106525cbc47964b0bdf3d2916d794e870169dbd0b4befd',
timestamp: 1590246978,
totalDifficulty: BigNumber { s: 1, e: 1, c: [ 19 ] },
transactions: [
'0xbdf2740b6a1ed58ec937f6d14a40befbd736df55bc247d25d16d6ee82bae7db5'
],
transactionsRoot: '0x407fd28af2c8c3208986b86b9f1a68229d7d8806be489c986ceb9036dc244030',
uncles: []
}
//异步
> web3.eth.getBlock(9,function(err,res){console.log(res)})
- 查询相应区块号或哈希值的区块中交易的数量
> web3.eth.getBlockTransactionCount(9)
1
交易相关操作
- 查询余额
//查询第1个账户的余额
// > web3.eth.getBalance('0x9f0316428ea5231b7116840df16ae0a768078ffd') 账户的哈希
> web3.eth.getBalance(web3.eth.accounts[1])
BigNumber { s: 1, e: 18, c: [ 49999, 99999999447756 ] }
- 交易查询
>web3.eth.getTransaction('0xbdf2740b6a1ed58ec937f6d14a40befbd736df55bc247d25d16d6ee82bae7db5')
{
blockHash: '0x7aa8a046b41db5caaf64ab527dcfdd283deb41e9a9ef7901b07ea8def687a9fe',
blockNumber: 9,
from: '0x613d104e6d80ce5a06e7987d39bbd4ee0ccd7656',
gas: 2000000,
gasPrice: BigNumber { s: 1, e: 0, c: [ 1 ] },
hash: '0xbdf2740b6a1ed58ec937f6d14a40befbd736df55bc247d25d16d6ee82bae7db5',
input: '0x60606040523415600e57600080fd5b60a98061001c6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f70d290d14603c57600080fd5b3415604657600080fd5b605a60048080359060200190919050506070565b6040518082815260200191505060405180910390f35b60006006820290509190505600a165627a7a723058209c556cf72bbb74d10d06054e5c38c2aaaa68a04f4f4014106c120d4d0c01fa450029',
nonce: 3,
to: null,
transactionIndex: 0,
value: BigNumber { s: 1, e: 0, c: [ 0 ] },
v: '0xa95',
r: '0x272a84024a654551dd91c0de9e403f13c845d575e974a73d6a00ff42267e3205',
s: '0x7bbad81d6b1c531d15bffe4e6fbfa7dd82402d83c5224eb4e40733802a494b9a'
}
- gas消耗量估计
//仅转账则消耗21000,加入data后会有所增加
>web3.eth.estimateGas({from:web3.eth.accounts[0],to:web3.eth.accounts[1],value:200000,data:"0x1781723939abcdef"})
21544
- 发送交易
//发送交易前
> web3.eth.getBalance(web3.eth.accounts[1])
BigNumber { s: 1, e: 18, c: [ 50000, 886987 ] }
//向1号账户发送交易,在发送交易前需要先解锁0号账户
//在geth中使用如下命令解锁0号账户
//personal.unlockAccount(personal.listAccounts[0])
>web3.eth.sendTransaction({from:web3.eth.accounts[0],to:web3.eth.accounts[1],value:100000,data:"0x6879ab"})
'0x0247659c53a6df654d033346ee32276d42459d37eb774d5564d03b3dbb086ce9'
//发送交易后(需挖矿上链)
> web3.eth.getBalance(web3.eth.accounts[1])
BigNumber { s: 1, e: 18, c: [ 50000, 986987 ] }
创建合约相关操作
- 法一,在本地使用geth的console命令行创建合约
- 编写solidity程序
//编写solidity程序,保存到HelloWorld.sol文件中
pragma solidity ^0.4.17;
contract HelloWorld{
string name = "yorick";
function getName() public view returns(string){
return name;
}function setName(string _name) public{
name = _name;
}function pureTest(string _name) pure public returns(string){
return _name;
}
}
- 使用solcjs编译solidity合约文件,生成bin和abi两个文件
# 使用solcjs编译solidity合约文件,生成bin和abi两个文件
$ solcjs --bin --abi HelloWorld.sol
HelloWorld.solHelloWorld_sol_HelloWorld.abiHelloWorld_sol_HelloWorld.bin
- geth启动私链
# geth启动私链
geth --datadir data1 --networkid 123 --rpc --rpcaddr 192.168.1.114 --rpcport 8989 --port 3000 --dev console
- 在geth的console中部署合约
// 定义两个临时存储abi和bin的变量
> var abi = [{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"pureTest","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]
> var code = "0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6103cb806101146000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317d7de7c14610053578063c47f0027146100e1578063d9e0101e1461013e57600080fd5b341561005e57600080fd5b610066610214565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a657808201518184015260208101905061008b565b50505050905090810190601f1680156100d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ec57600080fd5b61013c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506102bc565b005b341561014957600080fd5b610199600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506102d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101d95780820151818401526020810190506101be565b50505050905090810190601f1680156102065780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61021c6102e6565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b25780601f10610287576101008083540402835291602001916102b2565b820191906000526020600020905b81548152906001019060200180831161029557829003601f168201915b5050505050905090565b80600090805190602001906102d29291906102fa565b5050565b6102de6102e6565b819050919050565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061033b57805160ff1916838001178555610369565b82800160010185558215610369579182015b8281111561036857825182559160200191906001019061034d565b5b509050610376919061037a565b5090565b61039c91905b80821115610398576000816000905550600101610380565b5090565b905600a165627a7a72305820d86e8958616dc022d15b91ce8d01fc6e93855a28d1f57d16e586d232986153e60029"
// 使用abi创建合约
> var MyContract = eth.contract(abi)
// 实例化合约,并部署到区块链中,等待挖矿打包
> var contract = MyContract.new({from:eth.accounts[0],data:code,gas:4700000})
// 部署合约成功可以调用函数查看该合约的地址
> temp.address
"0xe1eebf02358f0888aa928d6b0a458783d2a17a11"
- 法二,通过remix将合约部署到本地(最简单)
- 在本地开启可以连接remix的私链
# 在本地开启可以连接remix的私链
geth --datadir data1 --networkid 123 --rpc --rpcaddr 192.168.1.114 --rpcport 8989 --port 3000 --dev --rpccorsdomain="http://remix.ethereum.org" --rpcapi web3,eth,debug,personal,net --vmdebug console
- 打开remix,编写solidity程序并编译
文章图片
1.png
- 编译成功后按如下配置remix的部署环境,其中的私链节点填写在启动geth时候暴露的ip:port,默认为 http://localhost:8545
文章图片
2.png
- 点击Deploy部署合约到本地私链
文章图片
3.png 在本地geth的日志中,可以看到挖矿成功,并将合约写入区块的信息
INFO [05-28|22:44:36.185] Setting new local accountaddress=0xE66c8e10ef6FD7888E8c98a0bC5514D66E42a74e
INFO [05-28|22:44:36.185] Submitted contract creationfullhash=0x1e32853201463114053d67691832a94407f1ad06f0ec17af73936ab87f0d19ad contract=0x9803466FDC1AE5651F8FaAb4ccD4682231536844
INFO [05-28|22:44:36.185] Commit new mining worknumber=6 sealhash=4d8af1…02b716 uncles=0 txs=0 gas=0 fees=0 elapsed=95.846μs
INFO [05-28|22:44:36.186] Sealing paused, waiting for transactions
INFO [05-28|22:44:36.186] Commit new mining worknumber=6 sealhash=e3645e…a0c0cb uncles=0 txs=1 gas=345798 fees=3.45798e-13 elapsed=1.074ms
INFO [05-28|22:44:36.187] Successfully sealed new blocknumber=6 sealhash=e3645e…a0c0cb hash=72fe7a…0cd95b elapsed=1.289ms
INFO [05-28|22:44:36.187]mined potential blocknumber=6 hash=72fe7a…0cd95b
INFO [05-28|22:44:36.188] Commit new mining worknumber=7 sealhash=c8812f…e27b0c uncles=0 txs=0 gas=0fees=0elapsed=625.283μs
INFO [05-28|22:44:36.188] Sealing paused, waiting for transactions
- 可以使用remix的图形化接口调用合约中定义的函数
文章图片
4.png
- 法三,将remix中编译自动生成的文件放入geth中,一键部署合约
- 编写好solidity合约程序,并编译。找到编译结果的详细信息,拷贝其中的 WEB3DEPLOY 内容
文章图片
5.png
- 将内容直接复制粘贴到本地geth的console中即可,调用address接口可以发现返回地址,说明已成功将合约部署到链上
> var helloworld = helloworldContract.new(
...{
......from: web3.eth.accounts[0],
......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b8280546001816001161561010......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce57825......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6103cb806101146000396000f30060606040526000357c0100000000000000000000000000000000000000000000000......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6103cb806101146000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317d7de7c14610053578063c47f0027146100e1578063d9e0101e1461013e57600080fd5b341561005e57600080fd5b610066610214565b604051808060200182810......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6103cb806101146000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317d7de7c14610053578063c47f0027146100e1578063d9e0101e1461013e57600080fd5b341561005e57600080fd5b610066610214565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a657808201518184015260208101905061008b565b50505050905090810190601f1680156100d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ec57600......data: '0x60606040526040805190810160405280600681526020017f796f7269636b00000000000000000000000000000000000000000000000000008152506000908051906020019061004f929190610060565b50341561005b57600080fd5b610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6103cb806101146000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806317d7de7c14610053578063c47f0027146100e1578063d9e0101e1461013e57600080fd5b341561005e57600080fd5b610066610214565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a657808201518184015260208101905061008b565b50505050905090810190601f1680156100d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100ec57600080fd5b61013c600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506102bc565b005b341561014957600080fd5b610199600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506102d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101d95780820151818401526020810190506101be565b50505050905090810190601f1680156102065780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61021c6102e6565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102b25780601f10610287576101008083540402835291602001916102b2565b820191906000526020600020905b81548152906001019060200180831161029557829003601f168201915b5050505050905090565b80600090805190602001906102d29291906102fa565b5050565b6102de6102e6565b819050919050565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061033b57805160ff1916838001178555610369565b82800160010185558215610369579182015b8281111561036857825182559160200191906001019061034d565b5b509050610376919061037a565b5090565b61039c91905b80821115610398576000816000905550600101610380565b5090565b905600a165627a7a723058200de0a16a70e995f846c9e671ed3786a04348e9180d8cea0c242d3511a895b5090029',
......gas: '4700000'
......}, function (e, contract){
......console.log(e, contract);
......if (typeof contract.address !== 'undefined') {
.........console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
.........}
......})
INFO [05-28|22:53:42.506] Setting new local accountaddress=0xE66c8e10ef6FD7888E8c98a0bC5514D66E42a74e
INFO [05-28|22:53:42.506] Submitted contract creationfullhash=0xbc723bad1013ffbe484b7751b06789728639f6dcfd65526545e0e10a0398aac3 contract=0x175400570fadfd92bd976bd498EFB76edaa3872b
null [object Object]
INFO [05-28|22:53:42.508] Commit new mining worknumber=8 sealhash=c1b44f…9d7c59 uncles=0 txs=0 gas=0 fees=0 elapsed=275.665μs
INFO [05-28|22:53:42.509] Sealing paused, waiting for transactions
undefined
> INFO [05-28|22:53:42.511] Commit new mining worknumber=8 sealhash=476d4f…6d4342 uncles=0 txs=1 gas=345798 fees=3.45798e-13 elapsed=2.994ms
INFO [05-28|22:53:42.513] Successfully sealed new blocknumber=8 sealhash=476d4f…6d4342 hash=2a11a0…8c2557 elapsed=4.395ms
INFO [05-28|22:53:42.513]mined potential blocknumber=8 hash=2a11a0…8c2557
INFO [05-28|22:53:42.514] Commit new mining worknumber=9 sealhash=e2b19c…2832a0 uncles=0 txs=0 gas=0fees=0elapsed=396.974μs
INFO [05-28|22:53:42.517] Sealing paused, waiting for transactions
null [object Object]
Contract mined! address: 0x175400570fadfd92bd976bd498efb76edaa3872b transactionHash: 0xbc723bad1013ffbe484b7751b06789728639f6dcfd65526545e0e10a0398aac3> helloworld.address
"0x175400570fadfd92bd976bd498efb76edaa3872b"
【java|web3js基本使用】法五,若合约已经部署到链上,则可以通过abi以及合约地址,得到合约
> var helloworldContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_name","type":"string"}],"name":"pureTest","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"}]);
undefined
> var contractAddress ="0x175400570fadfd92bd976bd498efb76edaa3872b"
undefined
> var helloWorld = helloworldContract.at(contractAddress)
undefined
> helloWorld.address
"0x175400570fadfd92bd976bd498efb76edaa3872b"
> helloWorld.getName()
"yorick"
推荐阅读
- 为RESTful服务实现HATEOAS
- 区块链|第一天 区块链技术入门
- 大数据|赛迪观点("城市大脑"建设典型实践及经验启示)
- 区块链|NFT艺术品交易平台
- 更新用户资源上的GET方法以使用JPA
- 使用Spring Boot初始化RESTful Web服务项目
- 为所有资源实现通用异常处理
- 使用自定义注释增强Swagger文档
- 为RESTful服务实现动态过滤