【问题标题】:Unable to interact with nodes on web with a angular app无法使用 Angular 应用程序与 Web 上的节点进行交互
【发布时间】:2020-05-28 03:56:01
【问题描述】:

我引用了信用证cordapp cordapp,它的作用相同,我复制了dist内容并将其放在资源中,但是当在我的cordapp中启动我的spring服务器并导航到我的节点端口时,我看不到ui,谁能帮忙关于这个。

我收到 404 错误,不知何故我的端口被我的 Angular 应用程序选中了.

这里是corda api文件内容:

@RestController
@RequestMapping("/api/trading/") // The paths for GET and POST requests are relative to this base path.
class MainController(rpc: NodeRPCConnection) {

    companion object {
        private val logger = LoggerFactory.getLogger(RestController::class.java)
    }

    private val myLegalName = rpc.proxy.nodeInfo().legalIdentities.first().name
    private val proxy = rpc.proxy

    /**
     * Returns the node's name.
     */
    @GetMapping(value = "me", produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun whoami() = mapOf("me" to myLegalName)

    /**
     * Returns all parties registered with the network map service. These names can be used to look up identities using
     * the identity service.
     */
    @GetMapping(value = "peers", produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun getPeers(): Map<String, List<CordaX500Name>> {
        val nodeInfo = proxy.networkMapSnapshot()
        return mapOf("peers" to nodeInfo
                .map { it.legalIdentities.first().name }
                //filter out myself, notary and eventual network map started by driver
                .filter { it.organisation !in (SERVICE_NAMES + myLegalName.organisation) })
    }

    /**
     * Displays all IOU states that exist in the node's vault.
     */
    @GetMapping(value = "trades", produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun getTrades() : ResponseEntity<List<StateAndRef<TradeState>>> {
        return ResponseEntity.ok(proxy.vaultQueryBy<TradeState>().states)
    }

    /**
     * Initiates a flow to agree an IOU between two parties.
     *
     * Once the flow finishes it will have written the IOU to ledger. Both the lender and the borrower will be able to
     * see it when calling /spring/api/ious on their respective nodes.
     *
     * This end-point takes a Party name parameter as part of the path. If the serving node can't find the other party
     * in its network map cache, it will return an HTTP bad request.
     *
     * The flow is invoked asynchronously. It returns a future when the flow's call() method returns.
     */

    @PostMapping(value = "create-trade", produces = arrayOf("text/plain"), headers = arrayOf("Content-Type=application/x-www-form-urlencoded"))
    fun createIOU(request: HttpServletRequest): ResponseEntity<String> {
        val counter = request.getParameter("counterParty")
        val tradeStatus = request.getParameter("tradeStatus")
        val userId = request.getParameter("userId")
        val assetCode = request.getParameter("assetCode")
        val orderType = request.getParameter("orderType")
        val txDate = request.getParameter("transactionDate")
        val sdf = SimpleDateFormat("dd/MM/yyyy")
        val transactionDate = sdf.parse(txDate)
        val transactionAmount = request.getParameter("transactionAmount").toDouble()
        val transactionFees = request.getParameter("transactionFees").toDouble()
        val transactionUnits = request.getParameter("transactionUnits").toDouble()
        val transactionPrice = request.getParameter("transactionAmount").toDouble()
        val transactionId = request.getParameter("transactionId")
        if (counter == null) {
            throw IllegalArgumentException("Query parameter 'Counter partyName' missing or has wrong format")
        }
        if (transactionAmount <= 0 ) {
            throw IllegalArgumentException("Query parameter 'Transaction Amount' must be non-negative")
        }
        val partyX500NameCounter = CordaX500Name.parse(counter)
        val counterParty = proxy.wellKnownPartyFromX500Name(partyX500NameCounter) ?:
        throw IllegalArgumentException("Target string \"$counter\" doesn't match any nodes on the network.")

        val producer = Producer()
        return try {
            val signedTx = proxy.startTrackedFlowDynamic(TradeFlow.Initiator::class.java,tradeStatus,counterParty,userId,assetCode,orderType,transactionAmount,transactionFees,transactionUnits,transactionId,transactionDate,transactionPrice).returnValue.getOrThrow()
            val mapper = JacksonSupport.createNonRpcMapper()
            val result = mapper.writeValueAsString(signedTx)
            producer.send(result)
            ResponseEntity.status(HttpStatus.CREATED).body("Transaction id ${signedTx.id} committed to ledger.\n")
        } catch (ex: Throwable) {
            logger.error(ex.message, ex)
            producer.send(ex.toString())
            ResponseEntity.badRequest().body(ex.message!!)
        }
    }

    /**
     * Displays all IOU states that only this node has been involved in.
     */
    @GetMapping(value = "getTrade", produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun getTransactionDetails(@RequestParam("linearID") linearID: String): ResponseEntity<List<StateAndRef<TradeState>>>? {
        if (linearID == null) {
            ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Linear Id cannot be null.\n")
        }
        val idParts = linearID.split('_')
        val uuid = idParts[idParts.size - 1]
        val criteria = QueryCriteria.LinearStateQueryCriteria(linearId = listOf(UniqueIdentifier.fromString(uuid)),status = Vault.StateStatus.ALL)
        return ResponseEntity.ok(proxy.vaultQueryBy<TradeState>(criteria=criteria).states)
    }

这是我的 Angular 6 app.route.ts 文件:

    import { LandingPageComponent } from './Landing-Page/landing-page/landing-page.component';
    import { Routes, RouterModule } from "@angular/router";


    const APP_ROUTES:Routes=[
        {
             path:'', component: LandingPageComponent
         }
    ]


export const APP_ROUTES_PROVIDER = RouterModule.forRoot(APP_ROUTES);

登录页面包含我在与节点交互时应该看到的 ui 内容

这是我的服务文件:

import { Injectable } from '@angular/core';
import { map } from 'rxjs/operators';
import { Http, Response, Headers, RequestOptions,URLSearchParams } from '@angular/http';
import { Subject } from 'rxjs';


@Injectable()
export class CordaContentService {
  payload;
  constructor(private http:Http) { }

  private trades = new Subject<any>();

  // Observable string streams
  tradeMethodCalled$ = this.trades.asObservable();

  getAllTrades() {
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    this.http.get('http://localhost:50005/api/trading/trades',{
     headers: headers
   }).pipe(map((res : any)=>res.json()))
   .subscribe(
    (res) => {
     this.payload = res;
     console.log('success');
     this.trades.next();
    }
   );
   }

我从 app.component.ts 类的 ngoninit 部分调用这个 getAllTrades 函数,但是当我输入这个 url 时,我得到 http 404 错误。 我运行了这个命令并将 dist 文件夹内容复制到我的 cordapp 资源文件夹中 ng build --prod --aot --build-optimizer 是不是我做错了什么?

【问题讨论】:

  • 如果您直接查看其余 url 而不是通过 Angular 应用程序会发生什么?你能从 Angular 应用程序中看到任何其他页面吗?角度应用程序是否正确部署?您的节点在哪个端口上启动?你是如何从你的 kotlin 类连接到它的?你在那里使用正确的端口吗?任何错误信息?任何堆栈跟踪?有日志吗?这里没有足够的信息来提供有效的帮助。
  • 当我直接从邮递员那里查看网址时,我得到的结果是我按照信用证cordapp中提到的过程进行的。我正在使用我的节点的端口。我已经提到了那里定义的其余 api。
  • 我的端口是 50005,理想情况下,我的登陆页面组件应该加载到这个 url localhost:50005 上,正如 route.ts 文件中提到的那样,但我什么也没看到跨度>
  • “我复制了 dist 内容并将其放在资源中” - 将哪个 dist 复制到哪个资源目录? “但是当在我的 cordapp 中启动我的 spring 服务器时”- spring 服务器不在你的 cordapp 中,它是一个单独的 jar。你是用 Spring Boot 打包的吗?您是否将其余 api 和网页作为 Spring bootJar 一起运行?还是别的什么?
  • 没有等级任务来运行服务器我只是在运行,对不起,我可能发音错误,并且正如 dist 文件夹的东西被转换 chk 这个github.com/corda/LetterOfCredit/blob/release/… 我这样做了

标签: angular corda


【解决方案1】:

根据上面和 cmets 的信息,我认为您可能在 Angular 应用程序中使用了错误的 url。

通常,如果您的 spring 服务器正确启动并调用正确的 API,您将不会看到 404 page not found 错误消息。

我建议你看看这里的例子:https://github.com/corda/samples-kotlin/blob/master/Advanced/obligation-cordapp/clients/src/main/kotlin/net/corda/training/server/MainController.kt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多