有一个疯狂的副作用,由于我的一些代码组合。我有一个名为wallet的bean,它有一个地址,我有一个getter和setter用于该字段。
我在jsp中有一个视图,它接受地址a和数量n的输入。关键是把n个虚拟硬币送到a。
以下是提交后的网址: http://localhost:8080/CaseStudy/wallet/transact?address=foo&amount=45&submit=Submit
我还有一个transaction类,它提供了一个创建事务的方法,该事务将发送者钱包和地址a作为字符串,amount n作为double。
我通过阅读上面的请求参数来调用它。
@GetMapping("/wallet/transaction")
public String postTransaction(@ModelAttribute("wallet") Wallet w, Model model,
@RequestParam("address") String address, @RequestParam("amount") double amount, HttpServletRequest request)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
Transaction t1 = new Transaction(w, address, amount);
model.addAttribute("transaction", t1);
return "transaction"; // a jsp page
为了完全公开,这里是我的事务构造函数方法。我不认为我需要给你完整的代码,因为我只是问这怎么可能发生,怎么可能。
public Transaction(Wallet senderWallet, String recipientAddress, double amount)
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, IOException {
super();
this.uuid = StringUtils.getUUID8();
try {
this.output = Transaction.createOutput(senderWallet, recipientAddress, amount);
} catch (TransactionAmountExceedsBalance e) {
e.printStackTrace();
System.out.println("No new transaction created. See stack trace above");
System.out.println("Returning to main program");
return;
}
try {
this.input = Transaction.createInput(senderWallet, this.output);
} catch (SignatureException e) {
e.printStackTrace();
}
this.senderWallet = senderWallet;
this.recipientAddress = recipientAddress;
this.amount = amount;
System.out.println("Valid New Transaction created");
}
它调用一些输入和输出生成函数。这只是为了制作简单的字典,这些字典将被序列化并通过网络发送。
现在钱包地址永远不会改变。我希望请求参数中发送的地址是收件人地址。我想我可以把它改成“?recipientaddress=”来解决这个问题
然而,我有一些错误,我可以
如果我把13发到保罗的地址,这就是我所期望的 {"output":{"paul":13.0,"fd4d4e3e":987.0},"amount":13.0,"address":"paul","publicKey":"TODO","UUID":"e01e4786","publicKeyInfo":"TODO"}
输出字典应该有两个字段,一个是收件人地址和要发送的金额,另一个是我的或发件人地址和我以前余额的剩余部分。
但这是我真正得到的。 {"output":{"pauladdr":987.0},"amount":13.0,"address":"pauladdr","publicKey":"TODO","UUID":"2b1a15d3","publicKeyInfo":"TODO"}
同样在日志中,它似乎用请求参数覆盖了钱包地址。
当我删除setter方法时,它在wallet中修复了它。我想我也可以通过将request param更改为'recipientaddress'来修复它,然后我可以保留setter,尽管我不需要setter。
我只想分析和了解发生了什么。这没有任何意义,但话说回来,框架和控制反转应用程序是自上而下工作的。他们对bean或类有最终的控制权,对吗?任何时候你有一个二传手,你给他们一个钩子。那么问题是“为什么”。为什么仅仅因为它共享了一个名称就要覆盖依赖类的字段?transaction接收一个wallet作为参数,并从作为modelattribute创建的wallet构造一个新的事务
@ModelAttribute("wallet")
public Wallet addWallet()
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
Wallet wallet = Wallet.createWallet();
return wallet;
}
用一个随机地址。它必须看到有一个地址的requestparam,它必须假设我想设置钱包的地址,即使我直接传递与签名一致的值
public String postTransaction(@ModelAttribute("wallet") Wallet w, Model model,
@RequestParam("address") String address, @RequestParam("amount") double amount, HttpServletRequest request){
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
Transaction t1 = new Transaction(w, address, amount);
}
它必须获取参数并用地址重置w wallet的值。如果我有一个完全不同的对象作为第四个参数,它也有一个地址设置器呢?这也会改变吗?
我知道依赖注入对于实现解耦非常有效。我只想有能力更好地理解这一切是如何运作的。在使用框架时,我经常遇到麻烦和困惑,因为我的思维是循序渐进的逻辑运作的。在使用框架的过程中,你必须从上到下理解你看不到的东西,从应用程序初始化到你编写的代码行。根据SpringMVC的逻辑,我不小心告诉它要更改钱包的地址?但是,即使它调用了wallet.setaddress
并且我删除了它,它也没有破坏代码。
当我开始学习编码时,我没想到会有这样的框架。我期望在机器逻辑、建立库等方面有更多的进展,但它们是好的和重要的,我现在明白为什么了。库导入如果做得不好,实际上可能是反模式的。框架有点像应用程序中的操作系统,不是吗?在某种程度上,您将控制权交给他们,并使用他们的api和结构。如果你按他们的规则玩,你不会真的失去任何控制,但他们在技术上仍然有控制权,因为控制权倒置。粗心的人经常会碰到像我这样的问题,这就是为什么不像香草语言那样,你必须从上到下理解事情,因为这就是控制流开始的地方,要做到这一点,你必须理解并看到不在你面前的东西。你必须用你的头脑和眼睛看事情。我说的对吗?掌握这方面编码的最佳方法是什么?
暂无答案!
目前还没有任何答案,快来回答吧!