CQ5/AEM Dispatcher not retaining charset information - character-encoding

When we pull content from our publish instances, we get a content type header that states that the content is "charset=utf-8". When this files is served from the dispatcher that charset information is missing. This isn't a problem for web pages which look at the encoding declared in the html, however there are a number of third party libraries, including one from Adobe, that processes this as iso-8859-1 if that content type declaration isn't there.
I'm attempting to determine if it's possible for the dispatcher to be configured to add this information.

Indeed the dispatcher caches only the content, with no headers. If the page is loaded from the cache, it'll behave pretty much like any other static file served by the Apache. The dispatcher itself doesn't have any charset configuration, but I think that adding
AddDefaultCharset utf-8
to the Apache configuration should fix the issue. More info can be found in the Apache docs.

This may help someone but if you've created from a Java servlet, make sure that you set up headers first. In author/publish, it seems able to handle if these aren't set up because of the other configuration and how the pages are accessed.
So the following (where you have your DOGET method), you need to specify your headers as the very first thing as otherwise the encoding won't be set correctly.
protected void doGet(#Nonnull SlingHttpServletRequest request, #Nonnull SlingHttpServletResponse response) throws IOException, ServletException {
response.setContentType(com.adobe.granite.rest.Constants.CT_JSON);
response.setCharacterEncoding(com.adobe.granite.rest.Constants.DEFAULT_CHARSET);
....
}
In my instance, AEM and web server had the correct info but the issue was that the setting of encoding and content type happened later on when it should be defined immediately.

Related

How to config Jetty to interpret correctly UTF-8 in filenames

After upgrading to eXist-db 4.7.0, we have now Jetty 404 errors for filenames with UFT-8 accented or Chinese characters.
Any idea if there is a config file to manage that?
For eg.:
HTTP ERROR 404
Problem accessing /.../dicoEnviro-fr/humanit%C3%A9.xml.
Reason: Document /.../dicoEnviro-fr/humanité.xml not found
Powered by Jetty:// 9.4.14.v20181114
Use Jetty 9.4.20.v20190813 (there are updates to UTF-8 handling of resources on java.nio.file.FileSystem present since 9.4.16.v20190411 that you need)
Since I don't know what eXist-db does to start Jetty, I'm going to assume it's embedded, and answer based on that assumption.
Make sure your ServletContextHandler or WebAppContext is declared to use a Base Resource that is defined as a PathResource object pointing to your directory location defined as a java.nio.file.Path object.
Advice about Base Resource declaration:
Do not use a String to define it, that winds up being a URLResource which works with URL references, not file system paths, and you'll have the problem you are experiencing.
Do not use a File to define it, as that winds up being a FileResource which is deprecated functionality, and known to have problems with UTF-8 references.
Ensure your java.nio.file.Path is an absolute path. (no relative paths)
Ensure your java.nio.file.Path is normalized. (no "//" or "/../" segments)

Log4j2 Property Replacement

In Log4j2 appenders it's useful to use the contextPath as the filename, as in:
filename="/logs/${web:contextPath}.log. This means one log configuration can be reused across multiple webapps.
However If a contextPath is /foo/bar this creates the file /logs/foo/bar.log. Is there anyway to replace the / in the contextPath with _ so the filename is /logs/foo_bar.log?
For me this is more useful than replicating the context path structure directly into the logs. I 've read up on the StringSubstitution docs and can't see anyway to do it, but if anyone has a solution it would be really helpful!
I don't think there is a way to do this out of the box. But you can easily create a custom lookup that does this.
Start by subclassing WebLookup, and replace '/' characters with underscores in the returned string.
Example of creating a custom Log4j2 lookup:
see the manual page, or this question.

Dropwizard: customize health check address and format

Is it possible to customize Dropwizrd's healthcheck output so that, e.g.: /health for healthchecks instead of /healthcheck and some output like {“status”: 200}.
I realise I could simply write a new resource that does what ever I need, I was just wondering if there is a more standard way to do this.
From what I have read on the 0.7.1 source code it's not possible to change the resource URI for healthchecks unfortunately, I highly doubt you can change the healthcheck format. I also remember people complaining about not being able to add REST resources to admin page, only servlets. Maybe on 0.8.0?
Here are the details of what I've tracked so far on the source code. Maybe I have misread or misunderstood something, so somebody could fix it.
Metrics has actually written AdminServlet to add healtcheck servlet in a way that it checks the servlet config whether the URI is defined or not.
this.healthcheckUri = getParam(config.getInitParameter(HEALTHCHECK_URI_PARAM_KEY), DEFAULT_HEALTHCHECK_URI);
But dropwizard doesn't provide a way to inject this configuration in any way on AbstractServerFactory.
handler.addServlet(new NonblockingServletHolder(new AdminServlet()), "/*");
NonblockingServletHolder is the one which is providing the config to AdminServlet but is created by AbstractServerFactory with empty constructor and provides no way to change the config.
I've thought of and tried to access the ServletHolder from the Environment object on Application.run method but the admin servlets are not created until after run method is run.
environment.getAdminContext().getServletHandler().getServlets()[0].setInitParameter("healthcheck-uri", "/health");
Something like this in your run() function will help you control the URI of your healthchecks:
environment.servlets().addServlet(
"HealthCheckServlet",
new HealthCheckServlet(environment.healthChecks())
).addMapping("/health");
If you want to actually control what's returned you need to write your own resource file. Fetch all the healthchecks from the registery, run them and return whatever aggregated value you want based on their results.

Hiding WSDL in JAX-WS

I'm, using JAX-WS in order to build and deploy web-services.
Everything is working properly, however I need to hide the WSDL. In other words, If the user goes to the following URL: http://foo.com/wm-ws/WMService2?wsdl, i don't want the WSDL to show.
I read that we could use the #WSDL annotation so i did that as follows:
#WebService(serviceName = "WMService2",
targetNamespace = "http://test.wmservice.soap/",
portName = "WMService2")
#WSDL(exposed = false)
public class WMService2
{
...
}
But this doesn't change anything..The WSDL is still showing. I've seen work-around where a filter is created, but i think it's an overkill.
Any ideas?
For starters, your client will likely require the WSDL at runtime. It is possible to get around this with hand-crafted client code or by including a local copy of the WSDL (which requires a bit of magic in an EE environment, namely packaging the WSDL in your artifact and specifying a wsdl-location in your wsimport (I can provide more info if desired; this is also a valid solution: JAX-WS client : what's the correct path to access the local WSDL?). This explains more about the dependency but it's also a good idea to have it available for interoperability: Why is WSDL required for Java Client at runtime?
With that said, it sounds like what you're actually trying to accomplish is restrict access to web resources, which is easily accomplished with a web.xml. Specifically you can add a security constraint,
<security-constraint>
<web-resource-collection>
<url-pattern>*?wsdl</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
although this will mean that you must set up authentication in your container and authenticate in your client (what is your container? client?). The url-pattern can be anything and the role-name * indicates any authenticated user may access the resource.
About security contraints: http://docs.oracle.com/cd/E19798-01/821-1841/bncbk/index.html

how to get locale information on a GWT application

In GWT I have to specify what locales are supported in my application. The code get compiled in various files, one for each locale (beside other versions), but I have to give my clients one only URL. This URL is supposed to be a page that should be displayed according to the locale preferred by the browser.
I dont't want to have an HTTP parameter for the locale since I want to forse the locale preferred by the browser.
How can this be coded in GWT?
Should I try to to this using apache rewrite rules? I thied it, but I think I cannot access such parameter easely in a rewrite rule.
Thanks a lot,
Giuseppe
I had the same problem as you, but as I really need to know the current locale (I'm requesting a second server for data that I want to be localizable) I found this class:
com.google.gwt.i18n.client.LocaleInfo#getCurrentLocale(). That should give you what GWT uses currently.
GWT has good support for internationalization. See this link. The i18nCreator command can help you to set up the internationalization infrastructure for similar to the way projectCreator and applicationCreator set up the GWT application.
If you have static strings (i.e. Invalid Entry!) that need to be internationalized, you don't need any additional flag to i18nCreator command to create the properties files and infrastructure.
If you have strings that need to accept parameters (i.e. Hello {0}), you need to pass the -createMessages flag to i18nCreator command to create the properties files and infrastructure.
Now your module needs to include the i18n module in your MyApplication.gwt.xml:
<inherits name="com.google.gwt.i18n.I18N"/>
Define a Java interface in the same package as your property files that extends Constants or Messages and defines methods (name matches the property entries) that all return string.
MyConstants.properties contains:
errorMessage=Invalid Entry!
MyConstants.java contains:
import com.google.gwt.i18n.client.Constants;
public interface myConstants extends Constants {
String errorMessage();
}
Now to access these internationalized Strings from you application:
public class MyApplication implements EntryPoint {
private static final MyConstants constants = (MyConstants)GWT.create(MyConstants.class);
public void onModuleLoad() {
final Label errorMessage = new Label(constants.errorMessage);
}
}
GWT implements the interface for you automagically.
You can get messages in a similar way.
Hopefully this can help you get started.
Unless I am reading the documentation incorrectly I don't think you have to do anything.
GWT and Locale
By making locale a client property, the standard startup process in gwt.js chooses the appropriate localized version of an application, providing ease of use (it's easier than it might sound!), optimized performance, and minimum script size.
The way I read it, as long as your module has added all the locale choices to it, it should be automatic?
Check this com.google.gwt.i18n.client.LocaleInfo.getCurrentLocale()
<inherits name="com.google.gwt.i18n.I18N"/>
<!-- Use browser-specified locale for i18n -->
<set-configuration-property name="locale.useragent" value="Y"/>
<!-- Specify locales your application support -->
<extend-property name="locale" values="en"/>
<extend-property name="locale" values="de_DE"/>
<extend-property name="locale" values="ru_RU"/>

Resources