Google maps autocomplete with JSF error with ÄÖÜ - jsf

we're using google maps autocomplete in our JSF application, but when we choose a name with öäü the backingBean gets eg. Ã as value. We have set our meta info of the site to utf-8, but this didn't help in this case.
we added it like this:
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places&key=AIzaSyChQPYNPhodC79W6-oGzlVgQJEwfFMG_bs" />
<script type="text/javascript" charset="utf-8">
function addGMapAutoComplete(componentId) {
var component = document.getElementById('createRequest:' + componentId);
if (component) {
new google.maps.places.Autocomplete(component);
}
}
</script>
and used as
<p:inputText id="pickupLocation"
value="#{createRequest.pickupLocation}" required="true"
onfocus="addGMapAutoComplete('location')"
style="width:350px" />
can anyone help with this issue?

This is a known issue with PrimeFaces. It's incorrectly using server's default encoding (which is often ISO-8859-1) for decoding POST request data of ajax requests, even though JSF/Facelets by itself already by default uses UTF-8 through all layers.
To overcome this, you need to manually set the POST request body encoding to UTF-8 by calling ServletRequest#setCharacterEncoding() with a value of "UTF-8" as early as possible in the request processing (before the parameters are ever parsed out of the POST request body). Most straightforward way would be using a servlet filter for this:
#WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
// ...
}
Or, if you happen to use JSF utility library OmniFaces already, then just use its ready-to-use CharacterEncodingFilter by adding the following entries to your webapp's web.xml:
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.omnifaces.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Related

Simple Jetty/JSF file upload won't submit

I've already looked at this one and the related tickets to no avail.
I have, what looks like the, simplest example possible
<h:form enctype="multipart/form-data" prependId="false">
<h:outputText value="File: "></h:outputText>
<h:inputFile value="#{configUploadController.uploadedFile}" />
<h:commandButton value="Save" type="submit" action="#{configUploadController.uploadFile}" style="color: red;"></h:commandButton>
</h:form>
I put a breakpoint in my uploadFile method but it never gits hit. when I remove the enctype from the form it does try to submit but then I get the obvious error...
javax.servlet.ServletException: Content-Type != multipart/form-data
And just for completeness, I remove the <h:inputFile> and enctype and can see my breakpoint being hit. When I set enctype to text/plain it DOESNT hit the breakpoint. However, when I set enctype to gibberish it DOES hit the breakpoint :(
Am I missing a dependency or config somewhere?
And in case it matters, my web.xml...
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- File(s) appended to a request for a URL that is not mapped to a web
component -->
<welcome-file-list>
<welcome-file>status.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
<listener>
<description>Initializes Oracle JSF</description>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<!-- Define the JSF servlet (manages the request processing life cycle for
JavaServer Faces) -->
<servlet>
<servlet-name>faces-servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- Map following files to the JSF servlet -->
<servlet-mapping>
<servlet-name>faces-servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
jsf-api-2.2.15
jsf-impl-2.2.15
el-api-2.2
el-impl-2.2
jetty 9.4.18
javax.servlet-api-3.1.0
Instead of working around with a servlet (as per other answer) the actual problem was Jetty needs the multipart config setting up per multipart request.
Simple way to do this would be to add a filter that adds it as necessary, eg.
public class LoginFilter implements Filter {
private static final String MULTIPART_FORM_DATA = "multipart/form-data";
private static final MultipartConfigElement MULTI_PART_CONFIG =
new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String contentType = request.getContentType();
if (contentType != null && contentType.startsWith(MULTIPART_FORM_DATA))
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, MULTI_PART_CONFIG);
filterChain.doFilter(request, response);
}
}
See also:
How to implement FileUpload in embedded Jetty?
So, I haven't spent the time to track down why but jetty doesn't appear to like multipart forms. I got round it by using a servlet. Solution looks like this...
I've gone with ajax approach and a HTML form so I can specify my action, that matches the servlets pattern...
<form action="upload/config" enctype="multipart/form-data" method="post">
<h:inputFile id="file" />
<br />
<h:commandButton type="submit" value="Upload">
<f:ajax execute="file" render="#all"/>
</h:commandButton>
</form>
And the servlet...
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.servlet.MultipartConfigElement;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.eclipse.jetty.server.Request;
#WebServlet("upload")
#MultipartConfig
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp) {
try {
// This needed to get access to the parts
MultipartConfigElement multipartConfigElement = new MultipartConfigElement((String)null);
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfigElement);
Part filePart = request.getPart("file");
try ( InputStream inputStream = filePart.getInputStream(); ) {
// Do what you want with your part
} catch (Exception e) {
resp.setStatus(500);
}
} catch (Exception e) {
resp.setStatus(500);
}
}
}

How to force .jsf file extension when .xhtml is typed directly in url

When using JSF, one can choose from several extensions like:
/faces/*
*.jsf
*.xhtml
Where the last one is recommended for JSF 2.2 at least.
But what if I wanted to use the .jsf extension, I get a problem here is that if someone were to type out of "curiosity" .xhtml then weird stuff could start to happen if you for example mix JSF tags with normal HTML tags.
So I know that GlassFish server's Admin Console for example forces the URL rewrite to .jsf if I type .xhtml, how can I do this ?
Two ways:
Simply restrict direct access to .xhtml files in web.xml.
<security-constraint>
<display-name>Restrict direct access to XHTML files</display-name>
<web-resource-collection>
<web-resource-name>XHTML files</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
See also JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output.
Create a servlet filter which listens on *.xhtml and redirects to *.jsf.
#WebFilter("*.xhtml")
public class FacesUrlRewriteFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String redirectURI = request.getRequestURI().replaceAll("xhtml$", "jsf");
String queryString = request.getQueryString();
if (queryString != null) {
redirectURI += "?" + queryString;
}
response.sendRedirect(redirectURI);
}
// ...
}
See also How to use a servlet filter in Java to change an incoming servlet request url?

Removing JSESSIONID in URL without using Filter and Wrapper

I have created a Filter listening on an url-pattern of /* which replaces the HttpServletRequest with a HttpServletRequestWrapper implementation.
I have a Servlet and in this Servlet am using h:graphicImage to render images fetching from Apache web server.
<h:graphicImage value="/locationInMyWebServer/myImage.jgp"></h:graphicImage>
When I hit the URL for accessing this page (containing image), the image was not getting displayed as JSESSIONID was getting appended to my image name. The URL that was getting formed was like below.
http:/myDomain/myServlet/../myImage.jpg;JSESSIONID=ABCDEFGHIJKLMM
Hence, I have used the Filter (more details about this filter is here) as stated in the beginning of my question.
From this Servlet there is a link for logging in. When a User logs in, same JSESSIONID is getting retained even after authentication. Since, Session ID is same before logging in and after a user logs in, this is leading to Session-fixation attacks.
How can I avoid using this filter and also solve my problem of JSESSIONID getting appended to images when I use h:graphicImage
PS: I can't use <img src> because my h:graphicImage is inside h:commandLink
Session Id was different before logging in and after logging in , before using this Filter
I have added the relevant code below.
Below code is from my web.xml which has entry for Filter
<filter>
<filter-name>URLSessionFilter</filter-name>
<filter-class>myPackage.web.filter.URLSessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>URLSessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
Code in my URLSessionFilter is below,
public class URLSessionFilter implements Filter
{
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
if (!(request instanceof HttpServletRequest))
{
chain.doFilter(request, response);
return;
}
HttpServletResponse httpResponse = (HttpServletResponse)response;
HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse)
{
public String encodeRedirectUrl(String url)
{
return url;
}
public String encodeRedirectURL(String url) {
return url; }
public String encodeUrl(String url) {
return url; }
public String encodeURL(String url) {
return url;
}
};
chain.doFilter(request, wrappedResponse);
}
public void init(FilterConfig filterConfig)
{
}
public void destroy()
{
}
}
There is a link in my Servlet on click of which login page will be displayed. Code is below,
<h:commandLink action="#{myBean.myMethod}">
<h:graphicImage value="/myLocInWebserver/myImage.jpg">
</h:commandLink>
In myBean.myMethod , am doing some DB clean up activities and redirecting to login page.
Another way is avoid the servlet container interpreting something as a URL. To accomplish that, you would avoid any of the special JSP or JSF tags, and directly use HTML tags. In your case - that could look like follows:
<h:commandLink action="#{myBean.myMethod}">
<img src="#{request.contextPath}/myLocInWebserver/myImage.jpg"/>
</h:commandLink>
No more <h:graphicImage> ...
You would still want your context path to be prefixed without any hardcoding - hence the use of #{request.contextPath}.
I recently came to this solution, as I was integrating JavaMelody with my application, and provided a link for admins to the tool. However somehow JavaMelody fails with the ;jsessionid appended. Hence, I am currently generating the URL as follows:
<a href="#{request.contextPath}/monitoring"
target="_blank"
class="ui-link ui-widget"
>
Java Melody Performance Monitoring
</a>
instead of the typical JSF solution
<p:link value="Java Melody Performance Monitoring"
href="/monitoring"
target="_blank"
/>
Which simply won't work.
The benefit of this solution is that I can now control this on a URL by URL basis, and I do not have to worry about setting <tracking-mode>COOKIE</tracking-mode> globally.

Use ISO-8859-1 encoding with JSF 2 on Jboss

I have a JSP Page which uses the following directive:
<%#page contentType="text/html; charset=iso-8859-1" pageEncoding="iso-8859-1"%>
Hence, forms within the page are sent using ISO-8859-1 encoding and the beans receive (in the setXXX() methods) Strings encoded according to this format.
I want to "translate" the JSP into JSF 2, which uses UTF-8 as default. How can I force JSF to use ISO-8859-1 and hence simulate the page directive?
I use Mojarra + richfaces on jboss 6.
Thank you!
Set the encoding attribute of the <f:view>.
<f:view encoding="ISO-8859-1">
Sticking to a non-Unicode encoding is however not recommended anymore these days. Your webapp would be not ready for world domination and you'd risk Mojibake when an enduser attempts to send Unicode-encoded data anyway (e.g. Hebrew, Cyrillic, Chinese, etc).
I didn't really understand the problem, but this allowed me to avoid Mojibake while using UTF-8 instead of ISO-8859-1:
public class EncodingFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
if (req.getCharacterEncoding() == null) {
req.setCharacterEncoding("UTF-8");
}
chain.doFilter(req, resp);
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
Strangely, without this filter I got Mojibakes although I didn't specify any kind of encoding. I also noticed that (filterConfig.getInitParameter("encoding")) in the init() method always returned null.

primefaces JSF P:fileUpload cannot get the response

I am facing a problem with <p:fileUpload> of PrimeFaces. I created a Facelet page to upload the Excel file as below:
<p:fileUpload fileUploadListener="#{blackListImportBean.xlsFileUpload}"
multiple="true" allowTypes="*.xls;*.xlsx" description="*.xls;*.xlsx"
sizeLimit="100000"/>
<h:commandButton actionListener="#{blackListImportBean.test}"
value="#{msg.SAVE}" action="test-page.xhtml" />
And bean java code as below:
public void xlsFileUpload(FileUploadEvent event){
// ...
}
public void test() {
// ...
}
When I click the button, the method test() is called and the method xlsFileUpload() is not invoked and an error prompts that it cannot find the method xlsFileUpload(), because the method need the parameter. When I remove the parameter, the page cannot find the method. Another issue which confused me is that I cannot get the upload file. I did it as per the documentation and I do not know what should I do.
Two questions:
1) Are you using Primefaces 2.X or 3.X?
2) What is on the stack trace? It probably contains the information as to why.
The file-upload component uploads the file on its own event sequence so that will get triggered when the user triggers the file upload. This can be automatic via the property auto="true". Alternatively it displays an "upload" button that causes the upload. As such, it is separated from the second action which is your test method.
Judging from the fact it can't find your method I would guess that either bean is unmanaged or that your environments are out of sync (clean build).
Also, try a simple test:
#ViewScope
public class TestBean
{
public void handleFileUpload(FileUploadEvent evt)
{
System.out.println("Handling Upload: " + evt.getFile());
UploadedFile upload = evt.getFile();
FacesContext.getCurrentInstance()
.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "File Uploaded", "This file is " + upload));
. . . //do whatever here....
}
}
//JSF Page
. . .
<h:form>
<p:messages id="messages" />
<p:fileUpload
fileUploadListener="#{testBean.handleFileUpload}"
multiple="true"
allowTypes="*.*;"
update="messages"
/>
</h:form>
. . .
If your filter is set you should see a series of messages displayed for each file that's uploaded. If not, you should get a useful error message. Also, be aware you need a fair amount of basic Apache libraries (CommonsFileUpload) on the path and odds are that this is causing your problem.
Don't forget to add this in your web.xml:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>
org.primefaces.webapp.filter.FileUploadFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

Resources