I was using below configureResponse() in wicket 1.4.9
protected void configureResponse() {
super.configureResponse();
WebResponse response = getWebRequestCycle().getWebResponse();
response.setHeader("Cache-Control", "no-cache, max-age=0,must-revalidate, no-store");
response.setHeader("Expires", "-1");
response.setHeader("Pragma", "no-cache");
response.setCharacterEncoding("text/html; charset=utf-8");
response.setLocale(new Locale(Constants.USER_LANG_PREF_ENG));
}
So now in wicket 6 configureResponse() is removed and they replaced with configureResponse(WebResponse response), So I tried to write above code using this method as shown below,
#Override
protected void configureResponse(WebResponse response) {
// TODO Auto-generated method stub
super.configureResponse(response);
response.setHeader("Cache-Control", "no-cache, max-age=0,must-revalidate, no-store");
response.setHeader("Expires", "-1");
response.setHeader("Pragma", "no-cache");
final String encoding = "text/html" + getMarkupType() + "; charset=utf-8";
response.setContentType(encoding);
final Locale originalLocale = getSession().getLocale();
getSession().setLocale(new Locale(Constants.USER_LANG_PREF_ENG));
}
Can anybody tell me that, this code will work same as previous one or I need to modify again?
It is almost the same but you don't really need it because this is what Wicket would do anyways for you.
Check the implementation of super.configureResponse(response); and org.apache.wicket.markup.html.WebPage#setHeaders(WebResponse).
Apart from this:
final Locale originalLocale = getSession().getLocale(); - originalLocale is not used
getSession().setLocale(new Locale(Constants.USER_LANG_PREF_ENG)); - this probably should be moved to YourApplication#newSession()
Related
I'm using Spring RestTemplate to perform POST request sending a PDF file. The filename contains some UTF-8 characters (e.g. é, è, à, ê, ë).
The problem is that after sending the request, on the other side where the request is received, the filename doesn't have the expected UTF-8 characters, and I have something like ?popi?.pdf instead.
I've tried to explicitly set UTF-8 charset in RestTemplate, but it still doesn't work.
Here is my code,
public SomeThing storeFile(InputStream content, String fileName) {
Charset utf8 = Charset.forName("UTF-8");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headersFile = new HttpHeaders();
headersFile.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headersFile.setContentDispositionFormData("file", fileName);
List<Charset> listCharSet = new ArrayList<Charset>();
listCharSet.add(utf8);
headersFile.setAcceptCharset(listCharSet);
InputStreamResource inputStreamResource = new InputStreamResource(content);
HttpEntity<InputStreamResource> requestEntityFile = new HttpEntity<>(inputStreamResource, headersFile);
MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
multipartRequest.add("file", requestEntityFile);
RestTemplate newRestTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
HttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
newRestTemplate.getMessageConverters().add(0, stringHttpMessageConverter);
newRestTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
FormHttpMessageConverter convForm = new FormHttpMessageConverter();
convForm.setCharset(utf8);
newRestTemplate.getMessageConverters().add(convForm);
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multipartRequest, header);
ResponseEntity<String> result = newRestTemplate.postForEntity(env.getProperty("core.endpoint") + "/documents", requestEntity, String.class);
}
according to rfc7578 when you POST a file with multipart/form-data you should use "percent-encoding" instead of filename*
NOTE: The encoding method described in [RFC5987], which would add a
"filename*" parameter to the Content-Disposition header field, MUST NOT be used.
it could be easyly realesed:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, new FormHttpMessageConverter() {
#Override
protected String getFilename(Object part) {
if (part instanceof Resource) {
Resource resource = (Resource) part;
try {
return URLEncoder.encode(resource.getFilename(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
} else {
return null;
}
}
});
Most likely the file encoding's system property of the used JVM hasn't been explicitly set, meanwhile the operating system where JVM runs is not using UTF-8 as the default charset. For instance, if JVM runs on Windows, and we don't specify the charset, the default value will be Windows-1252 instead.
Could you double check the JVM arguments of both applications that send and receive the file? Please ensure that it has -Dfile.encoding=UTF-8 argument before specifying the main class name.
Please also ensure that the application/service which receives the file has been configured to accept UTF-8 charset.
Feel free to also check the other possible related answers, if adding the file.encoding argument on JVMs doesn't help solving the problem,
How to get UTF-8 working in Java webapps?
Spring MVC UTF-8
Encoding
Code on client side :
#UiHandler("form")
void onFormSubmission(SubmitCompleteEvent event) {
hideProcessingPopUp();
if (event.getResults().contains("Exception")) {
// handle exception
}
}
Servlet code in doPost method:
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment;filename="
+ exportType + ".csv");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
response.getOutputStream(), "UTF-8"));
// Adding content
List<CustomObject> list = (List<CustomObject>) anonymousList;
for (CustomObject eachObject : list) {
writer.append(eachObject.getContent());
writer.newLine();
}
writer.flush();
// Gently close streams/writers.
close(writer);
return fileContent;
Servlet code is fine, as am getting expected data and file. Problem is with response not reaching the client side i.e., SubmitCompleteEvent. Please help me out, thanks in advance.
This is how browsers work; and the javadoc for FormPanel actually warns you about it:
The back-end server is expected to respond with a content-type of 'text/html', meaning that the text returned will be treated as HTML. If any other content-type is specified by the server, then the result HTML sent in the onFormSubmit event will be unpredictable across browsers, and the onSubmitComplete event may not fire at all.
I am trying to get GWT+RESTlet to communicate with a RESTful service, which is not "GWT aware".
On the GWT client, I do something like
Reference ref = new Reference("http://localhost:8080/control/programs/");
ProgramListResourceProxy clientResource = GWT.create( ProgramListResourceProxy.class );
clientResource.setReference( proxyRef );
clientResource.setFollowingRedirects( true );
clientResource.accept( MediaType.APPLICATION_JSON );
clientResource.accept( MediaType.APPLICATION_XML );
ProgramListResourceProxy resource = RestClient.createProgramListResource();
resource.retrieve( new Result<ArrayList<ProgramRef>>()
{
#Override
public void onFailure( Throwable caught )
{
while( caught != null)
{
Window.alert( "Error retrieving programs.\n" + caught.getMessage() );
caught = caught.getCause();
}
}
#Override
public void onSuccess( ArrayList<ProgramRef> result )
{
Window.alert( "Programs: " + result );
programs = result;
view.setRowData( toStringList( result ) );
}
});
If I request the resource from the browser, I get
[{"name":"niclas","link":{"action":"GET","path":"/control/programs/niclas/"}}]
as expected.
But when doing the code above in GWT, I get the popup alert telling me that there is a problem, and in the nested exception is;
Error retrieving programs.
Can't parse the enclosed entity because of its media type.
Expected <application/x-java-serialized-object+gwt> but was
<application/json>. Make sure you have added the
org.restlet.client.ext.gwt.jar file to your server.
The MediaTypes matches in the request/response and the traffic looks like this.
Request;
GET /control/programs/ HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Accept: application/json, application/xml
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Referer: http://localhost:8080/connect/Connect.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Response;
HTTP/1.1 200 OK
Date: Sat, 30 Mar 2013 15:46:04 GMT
Content-Type: application/json; charset=UTF-8
Date: Sat, 30 Mar 2013 15:46:04 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.1.2
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Transfer-Encoding: chunked
4E
[{"name":"niclas","link":{"method":"GET","path":"/control/programs/niclas/"}}]
Can anyone explain why Restlet is expecting "application/x-java-serialized-object+gwt" and not the set MediaType in the resource??
Is it related to using org.restlet.client.resource.ClientProxy? If so, is there another way to do these async requests with RESTlet??
I am using RESTlet 2.1.2 and GWT 2.2.0.
Thanks in Advance.
I usually use JsonpRequestBuilder with overlay types (in this example JsonVideoList):
JsonpRequestBuilder builder = new JsonpRequestBuilder();
builder.requestObject(url, new AsyncCallback<JsonVideoList>() {
#Override
public void onFailure( Throwable exception) {
}
#Override
public void onSuccess(JsonVideoList list) {
}
});
I found this issue searching for your problem in google, this might be connected.
The following might not be productive but you could also have a look to restyGWT for making rest calls.
End of the day there were several problems wrapped up in this, and I thought I'd better share my findings;
I didn't realize that I had a "same-origin" problem. This was solved by using a transparent proxy on the GWT serving port to my Rest Server. This also seems to correctly forward the authentication of the Rest server to the GWT application in the browser.
Restlet's packaging in Editions seems like a really good idea. But it was really difficult to get the IntelliJ IDEA to be able to set up the GWT debug environment with these plus a shared DTO module. I think I had other problems regarding Restlet's way to figure out which content types being used and what not. End of the day, I convinced myself to not bother with a shared DTO library and instead;
Server side uses Restlet's Jackson extension, and pojo classes as DTOs.
On the GWT side, I ask Restlet to only deal with Representation type and use the AutoBean feature in GWT to do the serialization. (See below)
The AutoBean is great;
public interface Program
{
String getName();
void setName( String name );
List<Block> getBlocks();
void setBlocks(List<Block> blocks);
List<Connection> getConnections();
void setConnections(List<Connection> connections );
public static class Factory
{
public static Program make() {
AutoBean<Program> ref = ModelFactory.instance.program();
return ref.as();
}
public static String toJson(Program ref) {
AutoBean<Program> bean = AutoBeanUtils.getAutoBean( ref );
return AutoBeanCodex.encode( bean ).getPayload();
}
public static Program fromJson(String json) {
AutoBean<Program> bean = AutoBeanCodex.decode( ModelFactory.instance, Program.class, json );
return bean.as();
}
}
}
To make the sample complete, my ModelFactory has creation methods for these, which are also fully handled by GWT;
public interface ModelFactory extends AutoBeanFactory
{
ModelFactory instance = GWT.create( ModelFactory.class );
AutoBean<Program> program();
AutoBean<ProgramRefList> programRefList();
:
}
One issue that wasn't obvious was how to handle top-level JSON lists, since AutoBean matches JSON keys with fields in the interfaces. But I found a neat little trick, which can be seen in the following snippet of the same program;
public interface ProgramRefList
{
List<ProgramRef> getList();
public static class Factory
{
public static ProgramRefList make()
{
AutoBean<ProgramRefList> ref = ModelFactory.instance.programRefList();
return ref.as();
}
public static String toJson( ProgramRefList ref )
{
AutoBean<ProgramRefList> bean = AutoBeanUtils.getAutoBean( ref );
return AutoBeanCodex.encode( bean ).getPayload();
}
public static ProgramRefList fromJson( String json )
{
json = "{ \"list\": " + json + "}";
AutoBean<ProgramRefList> bean = AutoBeanCodex.decode( ModelFactory.instance, ProgramRefList.class, json );
return bean.as();
}
}
}
The top-level list is faked into another object with a single key ("list" in this case) which then is reachable from the getList() method.
And this is then used very simply in the Rest client code;
ClientResource resource = RestClient.createProgramList( new Uniform()
{
#Override
public void handle( Request request, Response response )
{
Logger.trace( this, "handle(" + request + "," + response + ")" );
try
{
if( response.isEntityAvailable() )
{
String jsonText = response.getEntity().getText();
programs = ProgramRefList.Factory.fromJson( jsonText );
ArrayList<String> rowData = toStringList( programs );
view.setRowData( rowData );
}
}
catch( Exception e )
{
Logger.handleException( this, "loadProgramsList()", e );
}
}
} );
resource.get();
I have already tried a lot of approaches to send a xml file as string + pictures with a POST request using GWT on the client side. I can send the strings successfully, but I do not know how to send files (pictures) using the RequestBuilder, I am just able to send the strings.
Do someone know how to send files with a multipart/form-data POST request using GWT Client (RequestBuilder)?
P.S.: As I am not wishing to upload files, I don't need a uploader or something similar. I am developing a mobile app with Phonegap, and making pictures, which should be sent per POST request to a server (a third party service).
Thanks in advance!
Here some code:
public void sendPost() throws RequestException {
String boundary = createBoundary();
String xml = "<note> <to>Müller</to> <from>Jani</from> <heading>Erinnerung</heading> <body>Ich wohne in der Leipzigerstraße</body> </note>";
String requestData = getRequestData(boundary, xml);
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "http://localhost:8080/xxx/yyy");
builder.setHeader("Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + boundary);
builder.setHeader("Content-Length", Long.toString(requestData.length()));
try {
builder.sendRequest(requestData, new RequestCallback() {
public void onResponseReceived(Request request, Response response) {
}
public void onError(Request request, Throwable exception) {
exception.printStackTrace();
}
});
} catch (RequestException e) {
e.printStackTrace();
}
}
private String getRequestData(String boundary, String xml) {
String s = "";
s += "--" + boundary + "\r\n";
s += getRequestParameter("xml", xml + "");
s += "--" + boundary + "--\r\n"; // end
return s;
}
private String getRequestParameter(String key, String value) {
return "Content-Disposition: form-data; name=\"" + key + "\"\r\n\r\n"
+ value + "\r\n";
}
private String createBoundary() {
return "----GoneVerticalBoundary" + getRandomStr() + getRandomStr();
}
private String getRandomStr() {
return Long.toString(random.nextLong(), 36); //random -> DEFINED IN THE CLASS BODY
}
If you are using gwt + phonegap you should be using gwt-phonegap, right?
What I do in my apps, is to use gwtupload for the desktop version, and phonegap file transfer in the mobile. I use gwtupload servlet in the server side for both cases.
This is my code using gwt-phonegap:
FileUploadOptions options = new FileUploadOptions();
options.setFileKey("file");
options.setFileName("my_file.txt");
options.setMimeType("text/plain");
phonegap.getFile().createFileTransfer().upload(
"file:///my_path/my_file.txt",
"http://my-gwtupload-servlet/servlet.gupld",
options,
new FileUploadCallback() {
#Override
public void onSuccess(FileUploadResult result) {
if (result.getResponseCode() == 200) {
} else {
}
}
#Override
public void onFailure(FileTransferError error) {
Window.alert("Error sending the file, error-code: " + error.getCode());
}
});
I use deferred binding for selecting the appropriate implementation using phonegap.env:
<replace-with class="...UploadFilePhoneGap">
<when-type-is class="....UploadFile" />
<when-property-is name="phonegap.env" value="yes" />
</replace-with>
If you are looking for pure gwt solution then you need to work with FileUpload
If you do not mind using third party open source jar then you can try gwtupload
For locale issues just ensure you are using UTF-8 and GWT locale cookies and locale settings.
For all the people who wants to manage files and pictures on the client side, before sending them to the server, as Manolo has recommended, I suggest lib-gwt-file.
For people working with PhoneGap, I suggest enconding the pictures using Base64, and decoding on the server side (see class Base64Util)
I am trying to call remote servlet from GWT, actually the GWT-RPC doesn't seems to work, so I am trying to do it using the RequestBuilder.
Here's the code snippet:
String url = "http://some-remote-host:8888/GWTJSTest/SomeServlet?name=" + textBox.getText();
RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, url);
// requestBuilder.setHeader("Origin", "*");
// requestBuilder.setHeader("Access-Control-Allow-Origin", "*");
try
{
requestBuilder.sendRequest(null, new RequestCallback()
{
public void onResponseReceived(Request request, Response response)
{
if (response.getStatusCode() == 200)
{
Window.alert(response.getText());
}else
{
Window.alert(response.getText() + " : " + response.getStatusCode() + response.getStatusText());
}
}
public void onError(Request arg0, Throwable arg1)
{
Window.alert(arg1.toString());
}
});
} catch (RequestException e)
{
Window.alert("CATCH BLOCK: " + e.getMessage());
e.printStackTrace();
}
Actually, IE8 returns the data but after a warning message, but Firefox doesn't! Why is this?
As you see, I am trying to set some request headers but no way.
If you're trying to make a request to your own server and port (the same one that your GWT page is on), replace the first line with:
String url = "/GWTJSTest/SomeServlet?name=" + textBox.getText();
If you're trying to talk to a different server, or a different port on your own server, the Same Origin Policy will keep you from doing that. You'll need to proxy it from your own server.
The remote servlet is the one that needs to set the CORS header that you have:
Access-Control-Allow-Origin: *
Alternatively you can specify just your own domain instead of * if you don't want other domains interacting with the remote servlet.
I've added :
<add-linker name="xs" /> to .gwt.xml
And then replaces GWT-PRC by JsonpRequestBuilder (transforming JSONP between the server and the client)