• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

🌐Locale Message Updates in Joget Using Beanshell and REST API

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,605
Баллы
155

🧩 Overview


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.

✅ Goal: Automatically sync custom message entries (key–value–locale) into Joget’s system locale messages.
⚙ Technology Used: Beanshell, Joget REST API, CSRF-secured POST request.

⚙ How It Works

  1. 🗄 Fetch data from a custom table (app_fd_locale_msg_update) containing message keys, values, and locales.
  2. 🧠 Construct a JSON payload dynamically for each record.
  3. 🔐 Retrieve CSRF token securely from the Joget runtime.
  4. 🌍 POST the data to Joget’s internal message submission API endpoint.
  5. 🧹 Clean up by deleting the processed record from the table.

This makes localization updates dynamic, safe, and fully automated — without manual form submissions.

💻 Full Code


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 {
// 1️⃣ Fetch current record ID
String currentId = "#form.locale_msg_update.id#";

// 2️⃣ Prepare database connection
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);

// 3️⃣ Build API request
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) + "\"}]";

// 4️⃣ Include CSRF token
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");

// 5️⃣ Send POST request
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());

// 6️⃣ Delete processed record
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");
}



💡 Example Use Cases

  • 🌍 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.
🧰 Customization Tips


✅ Modify the source table name if your schema differs.
✅ Add WHERE clauses or filters to handle batch updates.
✅ If used with multiple locales, consider looping through a list of pending records.
✅ You can return a JSON status to display on form submission (optional).

🚀 Key Benefits

  • ⚙ 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.
🔒 Security Note

  • 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.
🏁 Final Thoughts


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.



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу