Changing character encoding for embedded application

Hi all,

I need to embed Vaadin app in a third party web page.
Web server and application server are in different domains.
Due to the nature of the application, using iframe is not an option. So I used VaadinXS add-on and embeded application inside a div.

Now my problem is:

Web page has non utf encoding (actually it is windows-1251).
And Vaadin servlet default encoding seems to be utf-8.

The question:

Is there a way to override character encoding for Vaadin UI.

David.

I managed to get correct encoding rendering by subclassing
XSApplicationServlet
and overriding its
service
method. like:


		RequestType reqType = getRequestType(request);
	
		if (reqType.equals(RequestType.UIDL)) {
			MyHttpServletResponseWrapper wrapper = new MyHttpServletResponseWrapper(response);
			super.service(request, wrapper);
			
			byte[] originalBytes = wrapper.getBytes();
			String originalResponseString = new String(originalBytes, "UTF-8");
			byte[] responseBytes = originalResponseString.getBytes("WINDOWS-1251");
			response.getOutputStream().write(responseBytes);			
		}
		else {
			super.service(request, response);
		}

Where HttpServletResponse is also subclassed:


        public class MyHttpServletResponseWrapper extends
		HttpServletResponseWrapper {

	protected ByteArrayOutputStream byteArrayStream;
	protected ServletOutputStream stream;
	
	public MyHttpServletResponseWrapper(HttpServletResponse response) {
		super(response);
		byteArrayStream = new ByteArrayOutputStream();
		stream = getNewServletOutputStream();
	}
	
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return stream;
	}
	
	
	private ServletOutputStream getNewServletOutputStream()	{
		ServletOutputStream stream = new ServletOutputStream() {
			
			@Override
			public void write(int b) throws IOException {
				byteArrayStream.write(b);
			}
		};
		
		return stream;
	}
	
	public byte[] getBytes(){
		return byteArrayStream.toByteArray();
	}
}

Now form fields and labels are rendered correctly, but if user enters values they arrive in wrong encoding.
I guess i have to decode request payload by myself. And convert it accordingly.

Any suggestions would be greatly appreciated.

Regards,
David.

Btw.
If AbstractCommunicationManager would respect request/response encoding information this issue would never be real issue.
Id would be sufficeint to set characterEncoding in request and response.
But deep in AbstractCommunicationManager’s
doHandleUidlRequest
PrintWriter for response is created in the following way:

        final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
                               new OutputStreamWriter(out, "UTF-8")));

never respecting if request/response character encoding is set.

In case anyone might become interested

Problem seems to be solved. (Some more tests have to be run to prove)

To override getRequestPayload I’ve created


public class MyContext extends JsonpWebApplicationContext {

	@Override
	public JsonpCommunicationManager getApplicationManager(
			Application application, AbstractApplicationServlet servlet) {
		JsonpCommunicationManager mgr = (JsonpCommunicationManager) applicationToAjaxAppMgrMap
				.get(application);

		if (mgr == null) {
			// Creates new manager
			try {
				mgr = new MyCommunicationManager(application, servlet);
			} catch (Exception e) {
				throw new RuntimeException(
						"Creating communication manager failed", e);
			}
			applicationToAjaxAppMgrMap.put(application, mgr);
		}
		return mgr;
	}
}

public class MyCommunicationManager extends JsonpCommunicationManager {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6442747312668280277L;

	public MyCommunicationManager(Application application,
			AbstractApplicationServlet servlet)
			throws NoSuchAlgorithmException, NoSuchPaddingException {
		super(application, servlet);
	}
	
	@Override
	protected String getRequestPayload(Request request) throws IOException {
		String originalPayload =  super.getRequestPayload(request);
		byte[] originalBytes = originalPayload.getBytes();
		String encodedPayload = new String(originalBytes, "UTF-8");
		return encodedPayload;
	}
}

in servlet class I’ve overriden getApplicationContext:

	@Override
	protected JsonpWebApplicationContext getApplicationContext(
			HttpSession session) {
		MyContext cx = (MyContext) session
				.getAttribute(MyContext.class.getName());
		if (cx == null) {
			cx = new MyContext();
			// save to session
			session.setAttribute(MyContext.class.getName(), cx);
		}
		// always ensure session in context (may be null if unserialized)
		cx.setSession(session);
		return cx;
	}

Now everything seems OK.

Please comment. I want to know if there is any better way to overcome the problem.

Kind regards,
David.