using freemarker and spring to construct templates - java

I am new to freemarker. I have a spring application that I am planning to use with freemarker. Templates will be stored in database and based on the login, I want to retrieve the template from database. Can any one tell me how to configure the freemarker in spring and get the html tags as a string after constructing the template. I did googling but I could not understand much.
I tried till this level. In spring I have done till this level. Finally I want html tags in a string.
// Spring freemarker specific code
Configuration configuration = freemarkerConfig.getConfiguration();
StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
// My application specific code
String temp = tempLoader.getTemplateForCurrentLogin();
Thanks.

To tie together the bits of code you posted, you can do something like this:
// you already have this bit
String templateText = tempLoader.getTemplateForCurrentLogin();
// now programmatically instantiate a template
Template t = new Template("t", new StringReader(templateText), new Configuration());
// now use the Spring utility class to process it into a string
// myData is your data model
String output = FreeMarkerTemplateUtils.processTemplateIntoString(template, myData);

This java method will process the freemarker template and will give html tags as String after constructing the template.
public static String processFreemarkerTemplate(String fileName) {
StringWriter stringWriter = new StringWriter();
Map<String, Object> objectMap = new HashMap<>();
Configuration cfg = new Configuration(Configuration.VERSION_2_3_24);
try {
cfg.setDirectoryForTemplateLoading(new File("path/of/freemarker/template"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
Template template = cfg.getTemplate(fileName);
template.process(objectMap, stringWriter);
} catch (IOException | TemplateException e) {
e.printStackTrace();
} finally {
if (stringWriter != null) {
try {
stringWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringWriter.toString();
}

Related

Java Spring Freemarker internationalization for templates

I am trying to do internationalization for my templates but i'm not sure if it's most efficient way to do it like this.
I extracted messages to resource bundle and i use MessageSource method getMessage(String var1, #Nullable Object[] var2, Locale var3) to get translation based on Locale, then i put it into model and process the template.
private String processTemplate(String templateName, String locale) {
try {
String greeting = messageSource.getMessage("messages.greeting", null, new Locale(locale));
Map<String, String> model = new HashMap<>();
model.put("greeting", greeting);
Template template = freemarkerConfiguration.getConfiguration().getTemplate(templateName);
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
} catch (IOException | TemplateException e) {
log.error("Error when processing template {}", templateName);
throw new EmailNotSentException();
}
}
My question is if there is more efficient way to process template in this manner ? Or it would be better to have internatiolization for templates ?
It depends. If you use those templates as your main ui renderers, internationalize the message is the better option. But if those templates are for "emailing" I'll opt for their internationalization.
In my application I have a similar use case, and I defined my templates like:
order-template-fr.ftl, order-template-es.ftl, order-template-en.ftl, ...
I resolve the template at runtime basing on the user's locale, using LOCALE_CONTRY.toLowerCase(). Example:
String template = "order-template-"+LOCALE_CONTRY.toLowerCase()+".ftl";

OpenSaml read metadata

I'm tring to read the metadata from an Idp using Open Saml 2. When i try to unmarshall the metadata openSaml show only this getter for attributes getUnknownAtrributes(). Looks like i am missing some point since when reading the Idp response SAML the code works very well. (it shows getAssertions() that returns a list of assertions).
I need to parse the metadata and find informations regarding the Idp.
Here the method
public Metadata metadataReader() {
ByteArrayInputStream bytesIn = new ByteArrayInputStream(ISSUER_METADATA_URL.getBytes());
BasicParserPool ppMgr = new BasicParserPool();
ppMgr.setNamespaceAware(true);
// grab the xml file
// File xmlFile = new File(this.file);
Metadata metadata = null;
try {
Document document = ppMgr.parse(bytesIn);
Element metadataRoot = document.getDocumentElement();
QName qName = new QName(metadataRoot.getNamespaceURI(), metadataRoot.getLocalName(),
metadataRoot.getPrefix());
Unmarshaller unmarshaller = Configuration.getUnmarshallerFactory().getUnmarshaller(qName);
metadata = (Metadata) unmarshaller.unmarshall(metadataRoot);
return metadata;
} catch (XMLParserException e) {
e.printStackTrace();
} catch (UnmarshallingException e) {
e.printStackTrace();
}
return null;
}
I suggest using a metadata provider to do the heavy lifting for you. FilesystemMetadataProvider is often a good fit.
I have a blog post that explains how to use it.

How to pass parameters to components rendered offline?

I have MyComponent:
public class MyComponent
{
#Parameter(required = false)
#Property
private String testParameter;
}
And I render it offline with the following code:
PageRenderRequestParameters pageRenderRequestParameters = new PageRenderRequestParameters(
"mycomponent", new ArrayEventContext(this.typeCoercer, ""), false);
StringWriter stringWriter = new StringWriter();
try
{
this.offlineComponentRenderer.renderPage(stringWriter,
new DefaultOfflineRequestContext(), pageRenderRequestParameters);
} catch (IOException e)
{
e.printStackTrace();
}
String htmlOutput = stringWriter.toString();
I don't know how to set the testParameter of MyComponent to imitate the following call:
<t:mycomponent testParameter="something" />
I think you failed to mention that you're using tapestry-offline, a 3rd party tapestry library.
You will need to create a page which includes the component before it can be rendered. If you want to make the parameter configurable, you will probably bind the property to the page activation context
Note: If you don't want the page to be visible on your website, you could probably annotate it with WhitelistAccessOnly and tweak the offline request so that it is whitelisted.

PayPal REST API java sdk - custom config file

Good afternoon all!
I use PayPal REST API java sdk and I want to have different configurations for different environments of my application. Here is how I'm trying to do so:
private static boolean IS_PRODUCTION = false;
private static String PAYPAL_ACCESS_TOKEN;
private static void initPayPal() {
InputStream is = null;
try {
is = ApplicationConfig.class.getResourceAsStream(
IS_PRODUCTION? "/my_paypal_sdk_config.properties" : "/my_paypal_sdk_config_test.properties");
PayPalResource.initConfig(is);
String clientID = ConfigManager.getInstance().getConfigurationMap().get("clientID");
String clientSecret = ConfigManager.getInstance().getConfigurationMap().get("clientSecret");
PAYPAL_ACCESS_TOKEN = new OAuthTokenCredential(clientID, clientSecret).getAccessToken();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(is);
}
}
and while trying to get the clientID I have
java.io.IOException: Resource 'sdk_config.properties' could not be found
Strange behavior - I thought I've just configured the sdk to use my own properties file.
Please advice how could I set up those settings properly!
So here is the solution I found:
Create an empty sdk_config.properties file in default location
Load your own properties:
private static void initPayPal() {
InputStream is = null;
try {
is = ApplicationConfig.class.getResourceAsStream(
IS_PRODUCTION ? "/my_paypal_sdk_config.properties" : "/my_paypal_sdk_config_test.properties");
Properties props = new Properties();
props.load(is);
PayPalResource.initConfig(props);
ConfigManager.getInstance().load(props);
String clientID = ConfigManager.getInstance().getConfigurationMap().get("clientID");
String clientSecret = ConfigManager.getInstance().getConfigurationMap().get("clientSecret");
PAYPAL_ACCESS_TOKEN = new OAuthTokenCredential(clientID, clientSecret).getAccessToken();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(is);
}
}
We have made some good improvements to the PayPal Java SDK on integration steps. We are removing the need for sdk_config.properties file as they do not work as well, specially for multi-configuration settings.
Now, all you do is create an APIContext instance with clientId, clientSecret, and mode. You pass that context object for any API operation from there on.
Here is how the code would look like for different configurations:
APIContext defaultContext = new APIContext(clientId1, clientSecret1, "sandbox");
APIContext sandboxContext = new APIContext(clientId2, clientSecret2, "sandbox");
APIContext someOtherContext = new APIContext(clientId3, clientSecret3, "live");
APIContext liveContext = new APIContext(clientId, clientSecret, "live");
// Now pass any of the above context in these calls, and it would use those configurations.
Payment payment = new Payment();
// Fill in all the details.
payment.create(defaultContext);
// Replace that defaultContext with any of those other contexts.
Here is the wiki page explaining that: https://github.com/paypal/PayPal-Java-SDK/wiki/Making-First-Call
I had the same error with SDK 0.11 version. I use my own properties file, but code still looked for "sdk_config.properties". I put it into root in my CLASSPATH, but still got the same error. Then I made obvious and horrible solution: put empty "sdk_config.properties" into "rest-api-sdk-0.11.0.jar" library. This street magic solved my problem.

Sending XML from Java to MSMQ - bodyType from VT_EMPTY to VT_BSTR

We work on a Java (Java EE) application, and we generate XML files in order to send them to a remote .NET application with MSMQ reading on their side.
The XML file is generated by JDom, like so :
// add elements...
Document doc = new Document(root);
String XmlData = new XMLOutputter(Format.getPrettyFormat().setOmitEncoding(true)).outputString(doc);
try {
SendFile( XmlData, "title" , "path");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessageQueueException e) {
e.printStackTrace();
}
Then we use this function, using the MsmqJava library to send the file :
private void SendFile(String data, String title, String outputPath) throws UnsupportedEncodingException, MessageQueueException{
String qname="name_of_the_queue";
String fullname= "server_path" + qname;
String body = data;
String label = title;
String correlationId= "L:none";
try {
Queue queue= new Queue(fullname);
Message msg= new Message(body, label, correlationId);
queue.send(msg);
} catch (MessageQueueException ex1) {
System.out.println("Put failure: " + ex1.toString());
}
}
They correctly receive the file, but they told us that the bodyType was set to "VT_EMPTY" while they wanted "VT_BSTR", and we haven't find a clue about how to fix this. If you know another lib who does the job, or a workaround to this one, we can change with no problem.
Thanks !
Looking at the documentation for the library you use, it is not possible using that library.
Jmsmqqueue also doesn't provide the functionality you need.
It seems sun also had an adapter: https://wikis.oracle.com/display/JavaCAPS/Sun+Adapter+for+MSMQ

Categories