- Регистрация
- 9 Май 2015
- Сообщения
- 1,605
- Баллы
- 155
Managing multiple language packs in Joget can become tedious when you frequently update UI text or labels.
This blog demonstrates how to automate locale message updates by fetching localized entries from a database table and submitting them to the Joget message API — all within a Beanshell script.
Fetch data from a custom table (app_fd_locale_msg_update) containing message keys, values, and locales.
Construct a JSON payload dynamically for each record.
Retrieve CSRF token securely from the Joget runtime.
POST the data to Joget’s internal message submission API endpoint.
Clean up by deleting the processed record from the table.
This makes localization updates dynamic, safe, and fully automated — without manual form submissions.
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import org.joget.apps.app.service.AppUtil;
import org.joget.commons.util.LogUtil;
import org.joget.commons.util.SecurityUtil;
public static String escapeJson(String value) {
if (value == null) return "";
return value.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
try {
//
String currentId = "#form.locale_msg_update.id#";
//
String appId = "", locale = "", messageKey = "", messageValue = "", app_version = "";
DataSource ds = (DataSource) AppUtil.getApplicationContext().getBean("setupDataSource");
Connection con = ds.getConnection();
try {
String sql = "SELECT * FROM app_fd_locale_msg_update WHERE id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, currentId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
appId = rs.getString("c_app_id");
locale = rs.getString("c_locale");
messageKey = rs.getString("c_messageKey");
messageValue = rs.getString("c_message");
app_version = rs.getString("c_app_version");
}
rs.close();
ps.close();
} finally {
if (con != null) con.close();
}
LogUtil.info("DB Values", "appId=" + appId + ", locale=" + locale + ", key=" + messageKey);
//
String appVersion = "#appDef.version#";
String apiUrl = "#request.baseURL#/web/json/console/app/" + appId + "/" + app_version + "/message/submit";
String messageId = messageKey + "_" + locale;
String jsonPayload = "[{\"id\":\"" + escapeJson(messageId) +
"\",\"key\":\"" + escapeJson(messageKey) +
"\",\"value\":\"" + escapeJson(messageValue) + "\"}]";
//
String csrfParam = SecurityUtil.getCsrfTokenName();
String csrfValue = SecurityUtil.getCsrfTokenValue(request);
String postData = "appId=" + URLEncoder.encode(appId, "UTF-8")
+ "&appVersion=" + URLEncoder.encode(appVersion, "UTF-8")
+ "&locale=" + URLEncoder.encode(locale, "UTF-8")
+ "&data=" + URLEncoder.encode(jsonPayload, "UTF-8")
+ "&" + csrfParam + "=" + URLEncoder.encode(csrfValue, "UTF-8");
//
HttpURLConnection conn = null;
BufferedReader reader = null;
try {
URL url = new URL(apiUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Cookie", "JSESSIONID=" + request.getSession().getId());
conn.setRequestProperty(csrfParam, csrfValue);
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
OutputStream os = conn.getOutputStream();
os.write(postData.getBytes("UTF-8"));
os.flush();
os.close();
InputStreamReader isr = conn.getResponseCode() >= 400
? new InputStreamReader(conn.getErrorStream(), "UTF-8")
: new InputStreamReader(conn.getInputStream(), "UTF-8");
reader = new BufferedReader(isr);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) response.append(line);
LogUtil.info("LocaleUpdater", "API Response: " + response.toString());
//
try {
con = ds.getConnection();
String deleteSql = "DELETE FROM app_fd_locale_msg_update WHERE id = ?";
PreparedStatement deletePs = con.prepareStatement(deleteSql);
deletePs.setString(1, currentId);
int deletedRows = deletePs.executeUpdate();
LogUtil.info("LocaleUpdater", "Deleted rows: " + deletedRows);
deletePs.close();
} finally {
if (con != null) con.close();
}
} finally {
try { if (reader != null) reader.close(); } catch(Exception e) {}
if (conn != null) conn.disconnect();
}
} catch(Exception e) {
LogUtil.error("LocaleUpdater", e, "Error in locale message update script");
}
Multilingual UI Management: Automatically add or modify translated strings without opening the message manager.
Bulk Localization Sync: Use this script in a scheduled process or post-form submission trigger.
Translation Review Workflow: Integrate it with a form where translators submit updates that get pushed into Joget once approved.
Automation: Removes manual locale message maintenance.
Accuracy: Ensures translation entries stay consistent across versions.
Integration: Works with internal Joget CSRF-secured APIs.
Reusability: Plug this into any app that maintains localized text data.
- Always use SecurityUtil.getCsrfTokenValue(request) to include the valid CSRF token.
- Avoid exposing internal API URLs publicly.
- Validate messageKey and locale before submission to prevent injection attacks.
This automation provides a robust way to manage dynamic language updates directly from your form data into the Joget platform — no manual clicks required.
By coupling Beanshell with Joget’s secure internal API, you gain a powerful extension point for localization and continuous deployment of translated UI assets.
Источник: