25

I have been trying to use a velocity Template with the following content:

Sübjäct $item

Everything works fine except the translation of the two Unicode characters. The result string printed on the command line looks like:

Sübjäct foo

I searched the velocity website and the web for this issue, and came up with different font encoding options, which I added to my code. But these don't help. This is the actual code:

velocity.setProperty("file.resource.loader.path", absPath);
velocity.setProperty("input.encoding", "UTF-8");
velocity.setProperty("output.encoding", "UTF-8");

Template t = velocity.getTemplate("subject.vm");
t.setEncoding("UTF-8");

StringWriter sw = new StringWriter();

t.merge(null, sw);       
System.out.println(sw.getBuffer());

How an I fix this issue?

Laurel
  • 5,965
  • 14
  • 31
  • 57
steve
  • 353
  • 1
  • 3
  • 5

4 Answers4

47

Have you tried using this syntax?

Template template = Velocity.getTemplate("subject.vm", "UTF-8");

That looks like it should do the right thing.

the_storyteller
  • 2,335
  • 1
  • 26
  • 37
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hi, thanks a lot. Concerning the other comment, velocity is actually an instance of VelocityEngine. But the code snippet is anyway a testcase, proper names only exists in production code ;) – steve Mar 01 '11 at 08:35
  • @Stony: Well the OP seems to think it worked for them, so it sounds like you've probably got proiblems somewhere else. I suggest you ask a new problem with a [mcve] showing what you've tried and what went wrong. – Jon Skeet Sep 03 '16 at 06:04
  • Sorry, I got the root cause finally. Your solution is working. The reason that doesn't work on my program is I used ve.setProperty("eventhandler.referenceinsertion.class", "org.apache.velocity.app.event.implement.EscapeXmlReference"); and the EscapeXmlReference broken the encoding. – Stony Sep 05 '16 at 01:26
  • @goblingift: Well not particularly, if the single-parameter overload uses the platform-default encoding, which is the case in many Java APIs. (I don't know if that's the case, but it seems like a reasonable supposition...) – Jon Skeet Jun 10 '17 at 10:42
2

If you're using VelocityEngine along with JavaMailSenderImpl class, don't forget to set the defaultEncoding property. Also, as mentioned above, try configuring input.encoding and output.encoding properties for the VelocityEngine class. I leave an example below.

Configuration file

<bean id="smtpSession" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:jboss/example/jndiName"/>
    </bean>
<bean id="javaMailSenderImpl" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="session" ref="smtpSession"/>
        <property name="defaultEncoding" value="UTF-8"/>
</bean>

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
        <property name="velocityProperties">
            <props>
                <prop key="input.encoding">UTF-8</prop>
                <prop key="output.encoding">UTF-8</prop>
                <prop key="response.encoding">UTF-8</prop>
                <prop key="resource.loader">file</prop>
                <prop key="file.resource.loader.class">org.apache.velocity.runtime.resource.loader.FileResourceLoader
                </prop>
                <prop key="file.resource.loader.path">${relative.path}/email-templates</prop>
                <prop key="file.resource.loader.cache">false</prop>                    
            </props>
        </property>
    </bean>
samblake
  • 1,517
  • 3
  • 16
  • 33
darkconeja
  • 348
  • 3
  • 7
1

My solution: add "-Dfile.encoding=UTF-8" to jvm option(quotes not included).

I try the above possible solution, none of then works for me.

After days of twisted search and explore, I guess my problem happen on velocitie's rendering the html file, because I found some wrongly displayed text is actually in GB2312 encoding, I realised that the encoding of the vm file is not correct when the page is been rendering(I guess).

user5465377
  • 31
  • 1
  • 2
  • That worked perfectly. Should this be the case to open an Issue on velocity template engine? The parameter should have forced the desired encode. – wdavilaneto Oct 08 '19 at 17:10
  • While this will work, it changes a lot of defaults for a lot of things across the whole JVM, which may not be what you want. Beware of changing the default when more-targeted options are available. – Christopher Schultz Feb 06 '20 at 19:06
0

If you're creating a JavaMailSenderImpl instance manually, you can set the encoding property this way:

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
Properties mailProperties = new Properties();
mailProperties.put("defaultEncoding", "UTF-8");
mailSender.setJavaMailProperties(mailProperties);

If you're using MimeMessageHelper, set the encoding as follows:

MimeMessageHelper helper = new MimeMessageHelper(mailSender.createMimeMessage(), true, "UTF-8");

Finally, for Velocity Engine, there are two ways to get/apply the template while setting the encoding:

Template template = Velocity.getTemplate("template", "UTF-8");
// or
velocityEngine.mergeTemplate("template", "UTF-8", velocityContext, stringWriter);
Toribio
  • 3,963
  • 3
  • 34
  • 48