2019-03-29 17:49

CaseInsensitiveContainerFactory 这个类的构造方法,如果传入 true 就会转成小写、传入 false 会转成小写,如果不传入则原样保留不转换

楼主的貌似是新需求, 感谢分享

2019-03-29 17:40

关于支付工作到的 API 在 jfinal weixin 中都有

2019-03-29 17:39

支付完成回调的 controller 中的 action 大致代码如下:

// 接收微信支付成功后回调的 action,如果响应延迟超过 5 秒
// 微信服务端会重发该回调,所以要注意对重发的回调去重
// 最简单方法是在支付记录中用一个字段做确认标记
public void weixinpay_callback() {
String callbackString = getRawData();
Map callbackPara = PaymentKit.xmlToMap(callbackString);

// 通过微信的回调参数 produect_id 可以得到用户 id,进而得到 Account 对象
Account account = srv.getAccountFromCallBackPara(callbackPara);

String ip = IpKit.getRealIp(getRequest());

// 生成微信回调的响应 xml,告知已确认了该笔支付
String orderXml = srv.makeOrder(account, callbackPara, ip, ClubPaymentService.notify_url);

// 发送给微信息服务端
renderText(orderXml);
}

2019-03-29 17:31

剩下的就是处理用户支付完成后,微信服务端的回调了,微信回调时会将 product_id 参数再发回给你,例如你前面生成的订单号是:yyyyMMddHHmmss-c1-accountId

其中的 accountId 就是你网站用户的 id 号,拿到用户 id 以及订单号,就可以继续完成后续流程了

2019-03-29 17:29

jfinal.com 中的微信扫码支付过程大致如下:
1:在 ClubService 生成一个订单号:

public class ClubService {

// 微信官方提供的二维码扫描支付的 url 调用接口
static final String qr_code_gen_url = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s";

/**
* 1:为了避免在生成二维码时就创建订单,需要在 product_id 中包含元信息
* yyyyMMddHHmmss-c1-accountId,其中 c1 表示 club 订阅 1 年
*/
public String genClubPaymentQrCodeString(Account account) {
String productId = genProductIdAlsoClubOrderId(account, years);
Kv signPara = Kv.create()
.set("appid", appid)
.set("mch_id", mch_id)
.set("product_id", productId)
.set("time_stamp", Long.toString(System.currentTimeMillis() / 1000))
.set("nonce_str", Long.toString(System.currentTimeMillis()));
String sign = PaymentKit.createSign(signPara, paternerKey);

return String.format(
qr_code_gen_url, sign, appid, mch_id,
productId,
signPara.getStr("time_stamp"),
signPara.getStr("nonce_str"));
}
}

注意看上面的代码 PaymentKit 创建了 sign 参数,最后用 String.format 将 qr_code_gen_url 中的参数更新成你项目中的实际参数

2:在 ClubController 中使用 ClubService.generatePaymentQrCodeString() 方法得到一个 String 参数,也即二维码数据,使用下面的代码生成二维码,让用户扫码支付:

public class ClubController extends BaseController {

@Inject
ClubPaymentService srv;

public void genClubPaymentQrCode() {
String qrCodeContent = srv.generatePaymentQrCodeString(getLoginAccount());
renderQrCode(qrCodeContent, 215, 215);
}
}

以上两步即可完成用户支付的核心流程

2019-03-29 15:32

那就得单步调试,看是哪个环境节乱的 @mekain

2019-03-29 15:21

配置一下:
UndertowServer.create(JFinalConfig.class)
.onStart( builder -> {
builder.setServerOption(UndertowOptions.URL_CHARSET, "GBK");
})
.start();


默认值是 UTF-8

2019-03-29 14:26

这都能想到,这是高手 @杜福忠

应该是 ctrl + c 复制字段名的时候将换行字符一并 copy 出来了, 手动输入创建字段名是不会出现这个问题的

2019-03-29 10:27

@蛋蛋丶 为什么不用 xxx.toInt() 来做? 前面已经说得很清楚了

2019-03-28 10:35

正在改版的新版本有搜索功能

目前可以在百度里面这么来玩:
关键字 site:jfinal.com

2019-03-28 10:33

@xiezhineng jfinal 生成器已经将 addMapping 自动化了,无需写这些代码

2019-03-28 09:46

表没有主键生成 model 的话, model.save()、model.update()、model.delete() 等很多 API 都无法工作

因为 model 是 Active Record 模式,这个模式的核心就是一个 model 对应一条数据库的 record,对应的起来的机制就是 “主键”, 失去主键就没有了这个机制,很多 API 自然就无法工作

当然,不排除有同学生成 model 后不使用那些 API,感谢分享

2019-03-28 09:44

异常核心信息:
Caused by: java.lang.NoSuchMethodError: com.jfinal.plugin.activerecord.Db.findById(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)

解决办法是:一是升级 jfinal 到最新版本, 二是将最后一个参数强制转化成 Object,或引入一个中间变量。

如果不想升级 jfinal 解决办法如下:
Db.findById("provinceinfo", "provinceinfo_id", (Object)record.getInt("provinceinfo_id"));

或者:
Object para = record.getInt("provinceinfo_id");
Db.findById("provinceinfo", "provinceinfo_id", para);

这个问题是由 JDK 8 引发的与 jfinal 无关。而 jfinal 新版本通过调整 findByIds 解决了这个问题

2019-03-28 09:36

如果本地 maven 库中的 jar 包确定无问题, 很可能是多个不同版本的 servlet 依赖存在,在 eclipse 下打开 pom.xml 中底部的 Dependency Hierarchy 视图可以确认

2019-03-27 07:18

纯文件访问权限问题,用 chmod 解决