昨晚在测试时遇到一个问题找了好久,就是我的QpayHelper这支程序里明明有用constructor injection
执行时却报nullpointer的错
开debug mode发现,我autowired的Bean是null...
找了好久都不知道哪边有问题,结果发现原来是因为我在另一支程序在call QpayHelper时
是用new的方式新增实例,
原来这麽做会导致里面没有被autowired到...又学到了一课
今天要来实作要拿来给我的网站使用的API
因为永丰的API在建立订单时,需要不重复的订单编号,而在MongoDB似乎没有get Sequence的功能
因此我打算先建立一个取流水号的功能,
首先,一样先建立一个Data Object
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import lombok.Data;
@Data
@Document
public class NextNum {
@Id
private String id;
private long no;
}
再来是repostory
import com.rei1997.vault.model.entity.NextNum;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface NextNumRepo extends MongoRepository<NextNum,String>{
}
最後再建一个service就完成了
@RequiredArgsConstructor
@Service
public class NextNumService {
private final NextNumRepo nextNumRepo;
public long getNum(){
Optional<NextNum> num=nextNumRepo.findById("no");
long nextNum=0;
if(num.isPresent()){
nextNum=num.get().getNo()+1;
num.get().setNo(nextNum);
nextNumRepo.save(num.get());;
}else{
NextNum n=new NextNum();
n.setId("no");
n.setNo(1);
nextNum=n.getNo();
nextNumRepo.save(n);
}
return nextNum;
}
这麽做是建立一个document来专忙放我的编号,
并且在每次取号後都+1,不过我不确定这麽做是不是个好作法...
搞不好会有重复取号的问题呢...晚点再回来看看有没有更好的做法
因为我觉得之前做好的QpayHelper就等於是Service了
接下来就来直接实作Controller
我後来先把QpayHelper的qpayHelper方法回传值改成String,直接回传json字串,要取哪些栏位来呈现就由前端去操作吧!
因为确定都只回传json字串,所以我在PostMapping直接加上了
produces = MediaType.APPLICATION_JSON_VALUE
也就是告诉浏览器 回传的资料是application/json格式
import com.rei1997.vault.api.Qpay.QpayHelper;
import com.rei1997.vault.api.Qpay.OrderCreate.OrderCreateReq;
import com.rei1997.vault.api.Qpay.OrderPayQuery.OrderPayQueryReq;
import com.rei1997.vault.service.NextNumService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.MediaType;
import lombok.RequiredArgsConstructor;
@RestController
@RequestMapping(value="api/v1/Qpay",produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class QpayController {
private final QpayHelper qpayHelper;
private final NextNumService service;
@PostMapping("/")
public String orderCreate(@RequestBody OrderCreateReq orderCreateReq){
//有些value由後端控制
cardParam.setAutoBilling(AutoBilling.Y);
orderCreateReq.setShopNo("NA0249_001");
orderCreateReq.setOrderNo(String.valueOf(service.getNum()));
orderCreateReq.setCurrencyID("TWD");
orderCreateReq.setCardParam(cardParam);
orderCreateReq.setReturnURL("http://localhost:8080/demo/api/v1/Qpay/query");
String jsonRes="";
try {
jsonRes=qpayHelper.qpayHelper(orderCreateReq, "OrderCreate");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println(e.toString());
}
return jsonRes;
}
@PostMapping("/query")
public String orderPayQuery(@RequestBody OrderPayQueryReq orderPayQueryReq){
String jsonRes="";
try {
jsonRes=qpayHelper.qpayHelper(orderPayQueryReq, "OrderPayQuery");
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.toString());
}
return jsonRes;
}
}
好,验收!
拿取得的url来贴浏览器
成功来到付款页
本来付款完成後预计是会跳转到付款结果的api
结果
发现原来因为永丰跳转时post到我的api的值是用post param的格式,而非json
我用的@ReuestBody没办法接收
因此改成@RequestParam
@PostMapping("/query")
public String orderPayQuery(@RequestParam Map<String,String>params){
...略
害我又要再用ObjectMapper转一次...
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
OrderPayQueryReq orderPayQueryReq=
mapper.convertValue(params, OrderPayQueryReq.class);
String jsonRes="";
又发现因为永丰给的key是大写开头,Objectmapper无法识别,
找到一个方法是再加上
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
让转换时不要区分大小写
@PostMapping("/query")
public String orderPayQuery(@RequestParam Map<String,String>params){
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
OrderPayQueryReq orderPayQueryReq=
mapper.convertValue(params, OrderPayQueryReq.class);
String jsonRes="";
try {
jsonRes=qpayHelper.qpayHelper(orderPayQueryReq, "OrderPayQuery");
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.toString());
}
return jsonRes;
}
拖了这麽多天终於成功啦
>>: JS 21 - 资料太多看得心很累?用 9 行程序码将资料转换为表格吧!
前天的趣味SQL, 经过大家热烈的响应,有提到 width_bucket() https://ith...
本篇内容要介绍Button元件, 除了认识Button的语法、属性外, 同时也要为按钮设置监听及触发...
前言 用了前面的范例,尤其是历史资料,会发现有可能重复输入的状况,或是重复资料输入不进去。这是我故意...
在 Day 06 和 Day 07 中,我们认识了 React.js 的两个 Components...
AlwaysInstallElevated 设定 在 Windows 当中有一种设定可以让非管理权限...