code: @Route(method = HttpMethod.GET, uri = "i18n/bundles/{file<.+>}.json")
      public Result getBundleResourceForI18Next(@QueryParameter("locales") String listOfLocales,
                                                @HttpParameter(HeaderNames.IF_NONE_MATCH) String ifNoneMatch) {
          // Parse the list of locale
          List<Locale> locales = new ArrayList<>();
          if (!Strings.isNullOrEmpty(listOfLocales)) {
              String[] items = listOfLocales.split(" ");
              for (String item : items) {
                  // Manage the 'dev' value (it's the default locale used by i18next
                  if ("dev".equalsIgnoreCase(item)) {
                      locales.add(InternationalizationService.DEFAULT_LOCALE);
                  } else {
                      locales.add(Locale.forLanguageTag(item));
                  }
              }
          }
  
          String etag;
          StringBuilder builder = new StringBuilder();
          for (Locale locale : locales) {
              builder.append(service.etag(locale));
          }
          etag = builder.toString();
  
          if (ifNoneMatch != null && ifNoneMatch.equals(etag)) {
              return new Result(Status.NOT_MODIFIED);
          }
  
          // i18next use a specific Json Format
          ObjectNode result = json.newObject();
          for (Locale locale : locales) {
              ObjectNode lang = json.newObject();
              ObjectNode translation = json.newObject();
              lang.set("translation", translation);
              Collection<ResourceBundle> bundles = service.bundles(locale);
              for (ResourceBundle bundle : bundles) {
                  for (String key : bundle.keySet()) {
                      populateJsonResourceBundle(translation, key, bundle.getString(key));
                  }
              }
              String langName = locale.toLanguageTag();
              if (locale.equals(InternationalizationService.DEFAULT_LOCALE)) {
                  langName = "dev";
              }
              result.set(langName, lang);
          }
          return ok(result).with(HeaderNames.ETAG, etag);
      }
docs: Gets the internationalized messages as a JSON document compliant with the I18Next format.
  
  @param listOfLocales the list of locales
  @param ifNoneMatch   the received ETAG if any
  @return the JSON document containing the messages