微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法在从 Maven SpringBoot 后端发送的 React 中获取 JSON 对象

如何解决无法在从 Maven SpringBoot 后端发送的 React 中获取 JSON 对象

我正在使用 Maven SpringBoot 后端在 React 中构建应用程序的前端。后端控制器从 Plaid API 调用获取数据并将其组装成一个 JSONObject,包含一个对象和一个数组。我可以在后端看到该对象正确填充了数据。

在前端,我使用 fetch() 请求来启动 API 调用,然后想将对象解析为 JSON 以便我可以使用它。 API 调用返回 200 状态,但返回的 JSON 对象为空。我不确定在后端和前端之间传递对象之间会丢失什么。

后端代码(返回的“loanResp”对象是我想要获取的对象):

package com.alumsum.backend.controllers;

import com.alumsum.backend.api.PlaidApiCaller;
import com.alumsum.backend.cache.UserLoanCache;
import com.alumsum.backend.model.FinUser;
import com.alumsum.backend.model.FinUserRepository;
import com.alumsum.backend.model.LoanAggregation;
import com.alumsum.backend.model.LoanAggregationRepository;
import com.alumsum.backend.model.PlaidFinancialInfo;
import com.alumsum.backend.model.PlaidFinancialInfoRepository;
import com.alumsum.backend.model.RegUser;
import com.alumsum.backend.model.RegUserRepository;
import com.alumsum.backend.utilities.Loancalculator;
import com.alumsum.backend.utilities.UserHandlingUtilities;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.plaid.client.request.ItempublicTokenExchangeRequest;
import com.plaid.client.response.ItempublicTokenExchangeResponse;
import com.plaid.client.response.LiabilitiesGetResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import retrofit2.Response;

import javax.validation.Valid;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Controller for Plaid API interactions.
 */
@Slf4j
@RestController
@RequestMapping("/plaid_api")
public class PlaidController implements PlaidApiCaller {

    @Autowired
    private RegUserRepository regUserRepository;
    @Autowired
    private PlaidFinancialInfoRepository plaidFinancialInfoRepository;
    @Autowired
    private UserLoanCache userLoanCache;
    @Autowired
    private LoanAggregationRepository aggregationRepository;
    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;
    @Autowired
    private FinUserRepository repository;


    @GetMapping("/plaid/plaid_fin_info")
    ResponseEntity<?> getPlaidUserInfo(@AuthenticationPrincipal OAuth2User principal) throws IOException {
        final JsonObject loanResp = new JsonObject();
        final JsonArray individualLoans =new JsonArray();
        final String userId = findUserIdFromAuthentication(principal);
        final RegUser user = regUserRepository.findRegUserById(userId);
        final String userName = user.getUserName();
        final List<PlaidFinancialInfo> group = plaidFinancialInfoRepository.findplaidFinancialInfoByUserName(userName);
        for (PlaidFinancialInfo finInfo : group) {
            final String accesstoken = finInfo.getAccesstoken();
            LiabilitiesGetResponse.Liabilities liabilities = getLiabilitiesInfo(accesstoken);
            List<LiabilitiesGetResponse.StudentLoanLiability> loans = liabilities.getStudent();
            //Account id in the cache
            for (LiabilitiesGetResponse.StudentLoanLiability loan : loans) {
                userLoanCache.add(loan.getAccountId(),loan,50000L);
                final JsonObject singleLoan =new JsonObject();
                singleLoan.addProperty("account_id",loan.getAccountId());
                singleLoan.addProperty("account_number",loan.getAccountNumber());
                singleLoan.addProperty("loan_name",loan.getLoanName());
                singleLoan.addProperty("loan_status",loan.getLoanStatus().getType());
                singleLoan.addProperty("is_overdue",loan.getIsOverdue());
                singleLoan.addProperty("expected_payoff_date",loan.getExpectedPayoffDate());
                singleLoan.addProperty("interest_rate",loan.getInterestRatePercentage());
                singleLoan.addProperty("principal",loan.getoriginationPrincipalAmount());
                singleLoan.addProperty("outstanding_interest",loan.getoutstandingInterestAmount());
                singleLoan.addProperty("loan_left",loan.getoriginationPrincipalAmount() + loan.getoutstandingInterestAmount());
                singleLoan.addProperty("minimum_payment",loan.getMinimumPaymentAmount());
                singleLoan.addProperty("last_payment",loan.getLastPaymentAmount());
                singleLoan.addProperty("origination_date",loan.getoriginationDate());
                singleLoan.addProperty("payments_made",loan.getPslfStatus().getPaymentsMade());
                singleLoan.addProperty("payments_left",loan.getPslfStatus().getPaymentsRemaining());
                individualLoans.add(singleLoan);
            }
        }
        loanResp.add("student_loan_info",individualLoans);
        final JsonObject loanAggregate = Loancalculator.aggregateLoans(loanResp);
        final Double totalDebt = loanAggregate.get("total_loan_debt").getAsDouble();
        final Double totalInterest = loanAggregate.get("average_interest_rate").getAsDouble();
        final String oktaId = UserHandlingUtilities.findOktaUserId(principal);
        final LoanAggregation loanAgggregation= new LoanAggregation(userName,totalDebt,totalInterest,oktaId);
        createOrUpdateLoanAggregation(loanAgggregation);
        loanResp.add("loan_aggregate",loanAggregate);

        return ResponseEntity.ok().body(loanResp);
    }

    private void createOrUpdateLoanAggregation(LoanAggregation loanAgggregation) {
        final String oktaId = loanAgggregation.getoktaId();
        final Optional<LoanAggregation> loanInfo = Optional.ofNullable(aggregationRepository.findLoanAggregationByOktaId(oktaId));
        final FinUser finUser = repository.findAllByRegUserId(oktaId).get(0);
        // if we find user,we PUT
        if(!loanInfo.isPresent()){
            createLoanAggregation(loanAgggregation);
            finUser.setLoanAggregations(loanAgggregation);
            repository.save(finUser);
        }
        else{
            final LoanAggregation updatedAggregation = loanInfo.get();
            updatedAggregation.setInterestRate(loanAgggregation.getInterestRate());
            updatedAggregation.setTotalDebt(loanAgggregation.getTotalDebt());
            updateLoanAggregation(updatedAggregation);
        }
    }

前端代码

import React,{Component} from 'react';
import { withCookies,Cookies } from 'react-cookie';
import { instanceOf } from 'prop-types';
import './QuickStats.scss';

class QuickStats extends Component {
    static propTypes = {
        cookies: instanceOf(Cookies).isrequired
    };

    constructor(props) {
        super(props);
        const {cookies} = props;
        this.state = {
            item: {},user: this.props.data,csrftoken: cookies.get('XSRF-TOKEN')
        };
    }

    async componentDidMount() {
        const {item,csrftoken} = this.state;
        const requestOptions = {
            method: 'GET',headers: { 
                'X-XSRF-TOKEN': csrftoken,'Accept': 'application/json','Content-Type': 'application/json'
            },credentials: 'include'
        };
        await fetch('/plaid_api/plaid/plaid_fin_info',requestOptions)
            .then(async response => {
                console.log(response);
                const data = await response.json();
                console.log("RESPONSE RECEIVED(3): ",data);
                // check for error response
                if (!response.ok) {
                    // get error message from body or default to response status
                    const error = (data && data.message) || response.status;
                    return Promise.reject(error);
                }
            })
            .then(data => {
                this.setState({item: data})
            })
            .catch((err) => {
                console.log("ERROR: ",err);
            });
    }

    render(){
        const {item} = this.state;
        return (
            <div className="quick-stats">
                <div>
                    <div className="container-heading text-left">Quick Stats</div>
                    <div className="display-flex mr-t5 flex-wrap">
                        <div style={{ backgroundColor: '#393e46',color: '#ffffff' }} className="tile flex-1 pd-20 text-center">
                            <div className="text-right mr-b5">
                                <img src={process.env.PUBLIC_URL + '/svg/information.svg'} alt="info" />
                            </div>
                            <div className="heading"></div>
                            <div className="sub-heading mr-t5">Principal remaining.</div>
                        </div>
                        <div style={{ backgroundColor: '#C9CAC8',color: '#4C4D4F' }} className="tile flex-1 pd-20 text-center">
                            <div className="text-right mr-b5">
                                <img src={process.env.PUBLIC_URL + '/svg/information.svg'} alt="info" />
                            </div>
                            <div className="heading"></div>
                            <div className="sub-heading mr-t5">You'll be debt-free march 2038.</div>
                        </div>
                        <div style={{ backgroundColor: '#288B6A',color: '#ffffff' }} className="tile flex-1 pd-20 text-center">
                            <div className="text-right mr-b5">
                                <img src={process.env.PUBLIC_URL + '/svg/information.svg'} alt="info" />
                            </div>
                            <div className="heading">%</div>
                            <div className="sub-heading mr-t5">Average interest rate of your loans.</div>
                        </div>
                    </div>
                </div>
            </div>
        )
    };
}

export default withCookies(QuickStats);

响应请求:

Request URL: http://localhost:3000/plaid_api/plaid/plaid_fin_info
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:3000
Referrer Policy: strict-origin-when-cross-origin
cache-control: no-cache,no-store,max-age=0,must-revalidate
connection: close
content-length: 2
content-type: application/json
expires: 0
pragma: no-cache
vary: Accept-Encoding
x-content-type-options: nosniff
x-frame-options: DENY
X-Powered-By: Express
x-xss-protection: 1; mode=block
Accept: application/json
Accept-Encoding: gzip,deflate,br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Type: application/json
Host: localhost:3000
Referer: http://localhost:3000/alumsum/dashboard
Sec-Fetch-Dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/88.0.4324.192 Safari/537.36
Response: {}

谁能确定我做错了什么,为什么响应返回空白而不是正确的数据?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。