Java Print API 如何让 CUPS 使用指定的打印用户?
结论
RequestingUserName 是 Java 打印请求中的属性,但 Java Print API 不保证每个 PrintService 后端都会将它作为 CUPS IPP 请求中的用户名发送,也不保证 CUPS 会采用该值。根据你描述的现象,当前 Java 打印路径最终使用的是 Java 进程对应的 Linux 用户。
在你确认有效的环境中,可以从 Java 调用 CUPS 的 lp 命令,并传入 -U john。CUPS 文档说明,-U 用于指定连接打印服务器时使用的用户名。实际作业记录采用哪个身份,也可能受服务器认证和策略影响。CUPS lp 手册
从 Java 调用 lp
如果打印内容已保存为文件,可以用 ProcessBuilder 分别传入参数,避免自行拼接 shell 命令:
Process process = new ProcessBuilder(
"lp",
"-d", "PRINTERDNS",
"-U", "john",
"document.ps"
).inheritIO().start();
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new IOException("lp failed with exit code " + exitCode);
}
这种写法与问题中验证过的命令形式相同。如果打印数据还在内存中,可以先写入临时文件,再传给 lp;也可以改用支持 IPP 的客户端库发送打印请求。
直接使用 Java 属性时
你可以保留现有的属性设置:
aset.add(new RequestingUserName("john", Locale.US));
仅添加这个属性,无法确认底层打印服务是否已将 requesting-user-name 传给 CUPS。可以检查当前 PrintService 实际发送的 IPP 请求,或查看 CUPS 调试日志。如果请求中没有该属性,或者 CUPS 根据认证信息采用了其他身份,就需要更换打印后端,或通过 CUPS/IPP 客户端显式提交。
Java 文档说明,JobOriginatingUserName 在可能时会取自认证身份;认证身份不可用时,才使用客户端提供的 RequestingUserName。这一定义并不保证特定 Java 打印后端或 CUPS 配置会按预期映射或采用该值。Java JobOriginatingUserName 文档
注意事项
lp -U john 可以让你当前的 CUPS 作业列表显示 john,但这不能证明操作系统已验证 john 的身份。如果打印服务器启用了认证,或限制客户端提交身份,服务器可能会拒绝请求,或改用已认证的用户名。请以目标 CUPS 服务上的实际作业记录为准。
备注:内容仅供参考。
