We have an existing Java Wicket 1.4 application which uses the HybridUrlCodingStrategy extensively:
mount(new HybridUrlCodingStrategy("/myurl", MyPage.class));
This results in our URL's looking like:
http://host/myurl/paramName1/paramValue1/paramName2/paramValue2
I would like to maintain this URL format in Wicket 1.5, however the HybridUrlCodingStrategy has been removed. In wicket 1.5, pages are mounted as:
mountPage("/myurl", MyPage.class);
Which results in traditional URLs like:
http://host/myurl?paramName1=paramValue2¶mName2=paramValue2
I have read that we should be using the MountedMapper class, but looking at the Wicket 1.5 examples, API docs, and source code, it is still not clear to me how to get the same behavior with MountedMapper as we are getting with the HybridUrlCodingStrategy.
Does anyone know how to do this?
Maybe something like this:
mountPage("/myurl/paramName1/${paramValue1}/paramName2/${paramValue2}", MyPage.class)
would work? Granted, you'd have to manually specify your parameters, which could be a lot more work.
The MountedMapper class javadoc explains how to use parameters.
The other option I can think of would be (Note: this is untested):
class MyPageParametersEncoder implements IPageParametersEncoder() {
public PageParameters decodePageParameters(Request request)
{
PageParameters parameters = new PageParameters();
int i = 0;
for (Iterator<String> segment = request.getUrl().getSegements().iterator(); segment.hasNext()) {
String key = segment.next();
String value = segment.next();
parameters.add(key, value);
}
return parameters.isEmpty() ? null : parameters;
}
public Url encodePageParameters(PageParameters pageParameters)
{
Url url = new Url();
for (PageParemeters.NamedPair pair : pageParameters.getAllNamed() {
url.getSegments().add(pair.getKey());
url.getSegments().add(pair.getValue());
}
return url;
}
}
mount(new MountedMapper("/myurl/", MyPage.class, new MyPageParametersEncoder());
No need of custom IPageParametersEncoder.
With mountPage("/myurl/paramName1/${paramValue1}/paramName2/${paramValue2}", MyPage.class) the URL will look like in 1.4 but the values will be reachable as StringValue value1 = parameters.get("paramValue1"). Similar for value2.
With mountPage("/myurl/${paramValue1}/${paramValue2}", MyPage.class) is the same according to extracting the values, just shorter URL will be used.
It also supports optional paramaters - #{optionalValue3}.
NOTE: A new class has been added to Wicket 1.5.2 for backwards compatibility with 1.4 style URL encoding. It's called UrlPathPageParametersEncoder - use that if you're migrating a wicket 1.4 app to 1.5 and you have bookmarkable page links of the style:
www.mysite.com/name1/value1/name2/value2
We had the exact same issue when migrating from 1.4 to 1.5. Any 1.4 app that has been live for a while would likely have a collection of links pointing to it from external sites on the web. You really want the Wicket 1.5 version of your app to be able to handle these existing hybrid links without generating an error.
When migrating to 1.5, without a 1.4 compatible IPageParametersEncoder implementation, you need to include the full parameter specification in every mount if you want to avoid making changes to each individual Page class that reads parameters. The implementation below means that is no longer necessary. Just mount the page as livid suggests above.
I'm submitting this .java file as a patch to the Wicket devs - they may include it in Wicket in the future to make it easy to implement backwards compatible URL parameter encoding for other 1.4 migrators.
I took luniv's sample code above and made a few small changes to get it compiling/working. The following should work as a parameter encoder to provide 1.4.x style parameter encoding in 1.5.
package org.apache.wicket.request.mapper.parameter;
import java.lang.*;
import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
import java.util.Iterator;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.Url;
import org.apache.wicket.request.mapper.parameter.PageParameters;
public
class HybridPageParametersEncoder implements IPageParametersEncoder
{
/**
* Encodes a URL in the form:
*
* /mountpoint/paramName1/paramValue1/paramName2/paramValue2
*
* (i.e. a URL using the pre wicket 1.5 Hybrid URL strategy)
*/
public Url encodePageParameters(PageParameters pageParameters)
{
Url url = new Url();
for (PageParameters.NamedPair pair : pageParameters.getAllNamed())
{
url.getSegments().add(pair.getKey());
url.getSegments().add(pair.getValue());
}
return url;
}
/**
* Decodes a URL in the form:
*
* /mountpoint/paramName1/paramValue1/paramName2/paramValue2
*
* (i.e. a URL using the pre wicket 1.5 Hybrid URL strategy)
*/
public PageParameters decodePageParameters(Request request)
{
PageParameters parameters = new PageParameters();
int i = 0;
for (Iterator<String> segment = request.getUrl().getSegments().iterator(); segment.hasNext(); )
{
String key = segment.next();
String value = segment.next();
parameters.add(key, value);
}
return parameters.isEmpty() ? null : parameters;
}
}
Related
Recently I analyzed crash reports form my app and found several stack traces which points to okhttp
My app doesn't depend on okhttp explicitly.
AFAIK okhttp version depends on Android OS version, and okhttp library by itself placed on device
To help with troubleshooting I decided to log okhttp library version, and looks like I found several useful classes for this
com.squareup.okhttp.internal.Version
okhttp3.internal.Version
Just to make sure that I didn't mistake I took com.android.okhttp.internal.http.HttpURLConnectionImpl class form stack-trace and tried to Class.forName it - success
Also I noticed that com.squareup.okhttp transformed to com.android.okhttp looks like at build-time, so totally I tried such variants
Class.forName("com.android.okhttp.internal.Version") -> java.lang.ClassNotFoundException
Class.forName("com.squareup.okhttp.internal.Version") -> java.lang.ClassNotFoundException
Class.forName("okhttp3.internal.Version") -> java.lang.ClassNotFoundException
Class.forName("com.android.okhttp.internal.http.HttpURLConnectionImpl") -> success
Can anyone explain why? What I missed?
Update
I have pulled okhttp.jar from my device adb pull /system/framework/okhttp.jar but it contains MANIFEST.MF only
from 4.xx google is using okhttp part of squareup
/**
* This implementation uses HttpEngine to send requests and receive responses. This class may use
* multiple HttpEngines to follow redirects, authentication retries, etc. to retrieve the final
* response body.
*
* <h3>What does 'connected' mean?</h3> This class inherits a {#code connected} field from the
* superclass. That field is <strong>not</strong> used to indicate whether this URLConnection is
* currently connected. Instead, it indicates whether a connection has ever been attempted. Once a
* connection has been attempted, certain properties (request header fields, request method, etc.)
* are immutable.
*/
public class HttpURLConnectionImpl extends HttpURLConnection {
private String defaultUserAgent() {
String agent = System.getProperty("http.agent");
return agent != null ? Util.toHumanReadableAscii(agent) : Version.userAgent();
}
https://github.com/square/okhttp/blob/master/okhttp-urlconnection/src/main/java/okhttp3/internal/huc/HttpURLConnectionImpl.java
http://square.github.io/okhttp/
everything depends on device - what os version u using because api is evolving, u can use reflections but u need know what field is on specific api
see https://github.com/square/okhttp/blob/master/CHANGELOG.md
to compare diffrent api versions use: https://android.googlesource.com/platform/external/okhttp/
u can try at the beginning
System.getProperty("http.agent");
edit:
via reflections
HttpURLConnection connection = (HttpURLConnection) new URL("http://google.com")
.openConnection();
Method method = connection.getClass().getDeclaredMethod("defaultUserAgent");
method.setAccessible(true);
String okEngineVersion = (String) method.invoke(connection, new Object[]{});
same as
String okEngineVersion = System.getProperty("http.agent");
and if u want to bother:
every class is treated the same way - > as equals ( no versioning - u can only check magic minor major number - java compiler version from class)
manifest of /system/framework/okhttp.jar doesn't contain version properties
if u want okhttp.internal.Version class then:
File file = new File("/system/framework/okhttp.jar");
// using javaxt-core lib
Jar jar = new Jar(file);
jar.getVersion();
// load dex
DexFile dexfile = DexFile.loadDex(file.getAbsolutePath(),
File.createTempFile("opt", "dex", _context.getCacheDir()).getPath(), 0);
Enumeration<String> dexEntries = dexfile.entries();
ClassLoader systemClassLoader = DexClassLoader.getSystemClassLoader();
while (dexEntries.hasMoreElements()) {
String className = dexEntries.nextElement();
Class<?> aClass = systemClassLoader.loadClass(className);
}
conclusion: If you want to avoid crash of app from library changes delivery
own version of library and load classes on the fly or compile with apk
I'm working on maintenance project which was developed with GWT version 1.x. Now I have to add some extra features in the same project and for that I have to inject external JavaScript file into GWT application. So I have done a bit of research to achieve the same and I can understand that I can inject the external JavaScript with the help of ScriptInjector class [Source]. but this class is available in GWT version GWT 2.7.0 and I'm using the older version of GWT.
So I would like to know that Can I inject the external JavaScript file without ScriptInjectorclass?
Maybe you can copy the sources of ScriptInjector into your project:
https://gwt.googlesource.com/gwt/+/master/user/src/com/google/gwt/core/client/ScriptInjector.java
public class JavaScriptInjector {
private static ScriptElement createScriptElement() {
ScriptElement script = Document.get().createScriptElement();
script.setAttribute("type", "text/javascript");
script.setAttribute("charset", "UTF-8");
return script;
}
protected static HeadElement getHead() {
Element element = Document.get().getElementsByTagName("head")
.getItem(0);
assert element != null : "HTML Head element required";
return HeadElement.as(element);
}
/**
* Injects the JavaScript code into a
* {#code <script type="text/javascript">...</script>} element in the
* document header.
*
* #param javascript
* the JavaScript code
*/
public static void inject(String javascript) {
HeadElement head = getHead();
ScriptElement element = createScriptElement();
element.setText(javascript);
head.appendChild(element);
}
}
This works if you have your JavaScript as a TextResource. If you want to load from a URL, you can specify the element.setSrc(yourURL) instead of element.setText(javascript). You can also load the javascript from the URL as a HTTP GET and do the setText anyway.
Environment NetBeans 6.9.1, GlassFish 3.1 + METRO 2.1
I want to make a JSF page that lists all available operations in a web service. I already have a File instance containing the WSDL file. Given these, how should I go on with listing only the available operations. What would be the best way?
Thanks in advance!
Use wsdl4j
import java.util.Map;
import javax.wsdl.Definition;
import javax.wsdl.Types;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
public class WSDLInspect {
public static void main( String[] args ) throws Exception {
WSDLFactory factory = WSDLFactory.newInstance();
WSDLReader reader = factory.newWSDLReader();
// pass the URL to the reader for parsing and get back a WSDL definiton
Definition wsdlInstance
= reader.readWSDL( null, "xxx" );
// get a map of the five specific parts a WSDL file
Types types = wsdlInstance.getTypes();
Map messages = wsdlInstance.getMessages();
Map portTypes = wsdlInstance.getPortTypes();
Map bindings = wsdlInstance.getBindings();
Map services = wsdlInstance.getServices();
/** Do other stuff with information **/
}
}
What is the best way to implement GWT Server Side Internationalization?
Use native Java properties files (not sure how to read and how to locate the right language file) (unicode string need to be ASCII encoded)
Use GWTI18N.java - GWT module which gives you seamless use of GWT I18N on both the client and the server and uses "java.lang.reflect.Proxy method"
Use Kotori I18N - ...
Other ideas?
How can I find and pass localization from client to sever?
On the server side I have an Servlet which still doesn't use any GWT dependant source, is it better not to do so?
I found this solution and it looks very good
gwt-i18n-server - Provides a simple support of gwt i18n feature on the server side
The aim is to permit to the GWT developer to use their Constants and Messages interfaces on the server side (See internationzation). The implementation is based on java reflect api. It loads the properties files from the classpath (same folder than the interface). It supports Constants, ConstantsWithLookup, Messages (plural too). The licence is LGPL.
Client current locale can be found this way:
LocaleInfo.getCurrentLocale().getLocaleName()
Following other threads here in SO, I came up with this solution that also considers the encoding used for the properties files (which can be troublesome as ResourceBundle uses by default "ISO-8859-1"):
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;
public class MyResourceBundle {
// feature variables
private ResourceBundle bundle;
private String fileEncoding;
public MyResourceBundle(Locale locale, String fileEncoding){
this.bundle = ResourceBundle.getBundle("com.app.Bundle", locale);
this.fileEncoding = fileEncoding;
}
public MyResourceBundle(Locale locale){
this(locale, "UTF-8");
}
public String getString(String key){
String value = bundle.getString(key);
try {
return new String(value.getBytes("ISO-8859-1"), fileEncoding);
} catch (UnsupportedEncodingException e) {
return value;
}
}
}
The way to use this would be very similar than the regular ResourceBundle usage:
private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)
Or you can use the alternate constructor which uses UTF-8 by default:
private MyResourceBundle labels = new MyResourceBundle("es");
I want to do what's described in question 724043, namely encode the path components of a URI. The class recommended to do that is URIUtil from Commons HttpClient 3.1. Unfortunately, that class seems to have disappeared from the most recent version of HttpClient. A similarly named class from HttpClient 4.1, URIUtils, doesn't provide the same functionality. Has this class/method been moved to some other library that I'm not aware of or is it just gone? Am I best off just copying the class from the 3.1 release into my code or is there a simpler way?
The maintainers of the module have decreed that you should use the standard JDK URI class instead:
The reason URI and URIUtils got replaced with the standard Java URI was
very simple: there was no one willing to maintain those classes.
There is a number of utility methods that help work around various
issues with the java.net.URI implementation but otherwise the standard
JRE classes should be sufficient, should not they?
So, the easiest is to look at the source of encodePath from the 3.1 release and duplicate what it does in your own code (or just copy the method/class into your codebase).
Or you could go with the accepted answer on the question you referred to (but it seems you have to break the URL into parts first):
new URI(
"http",
"search.barnesandnoble.com",
"/booksearch/first book.pdf",
null).toString();
This can be achieved using org.apache.http.client.utils.URIBuilder utility in httpclient-4.X () as follows.
public static String encodePath(final String path) {
if(path.length() == 0)
return "";
else
return new URIBuilder().setPath(path).toString();
}
You can use Standard JDK functions, e.g.
public static String encodeURLPathComponent(String path) {
try {
return new URI(null, null, path, null).toASCIIString();
} catch (URISyntaxException e) {
// do some error handling
}
return "";
}