Listening for fragment changes in the browser address with Jxbrowser - jxbrowser

I would like to listen for address changes. So far I have been able to use:
browser.addStatusListener((StatusEvent event) -> {
listener.handle(browser.getURL());
});
To create my own handler which is called when the address changes. But I just discovered that this approach does not work when an fragment is added to the address. E.g. a change from "http://example.com" to "http://example.com#hello" won't result in a StatusEvent. How do I archive this with JxBrowser?

The StatusListener class is not designed for tracking address changes.
In order to handle current browser URL changes, I suggest that you register your custom LoadListener and listen the DocumentLoadedInMainFrame event which indicates that a new document with a new URL was loaded in Browser instance. After you caught the DocumentLoadedInMainFrame event, you can get browser URL invoking the Browser.getURL() method. Please take a look at the code sample below:
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.events.LoadAdapter;
import com.teamdev.jxbrowser.chromium.events.LoadEvent;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class LoadHandlerSample {
public static void main(String[] args) {
Browser browser = new Browser();
BrowserView view = new BrowserView(browser);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(view, BorderLayout.CENTER);
frame.setSize(700, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
browser.addLoadListener(new LoadAdapter() {
#Override
public void onDocumentLoadedInMainFrame(LoadEvent event) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
System.out.println("Document loaded: " + event.getBrowser().getURL());
}
});
}
});
browser.loadURL("http://www.google.com");
}
}

Related

I got this email from google play console team regarding my app. "your app uses software that contains security vulnerabilities for users"

JavaScript Interface Injection
Your app(s) are using a WebView that is vulnerable to JavaScript interface injection.
To address this issue, follow the steps in this Google Help Center article.
in.glg.rummy.activities.RummyWebView.webViewSettings
I am thinking this file must be the case but not sure.
package in.glg.rummy.activities;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import in.glg.rummy.R;
public class RummyWebView extends Activity {
// String url="https://www.tajrummy.com/promotions/x/";
String url="http://rh.glserv.info/static_files/html5/gamerh.html";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rummy_activity_webview);
webViewSettings();
}
WebView webView;
public static String WebSessionId = "";
String webViewFunction = "androidFunction";
private void webViewSettings()
{
webView = findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
webSettings.setSupportZoom(true);
webSettings.setDefaultTextEncodingName("utf-8");
RummyJavaScriptInterfaceDemo javaScriptInterfaceDemo
= new RummyJavaScriptInterfaceDemo(this,webView);
webView.addJavascriptInterface(javaScriptInterfaceDemo, webViewFunction);
webView.loadUrl(url);
webView.setWebViewClient(new WebViewClient(){
public void onPageFinished(WebView view, String url){
//"javascript:<your javaScript function"
webView.loadUrl("javascript:init('" + WebSessionId + "')");
}
});
}
}
I tried commenting above code and app is working fine since we are not using rummy code

Infinispan cluster with Karaf instances

we are very new to Infinispan and also quite new to Apache Karaf. Installing Infinispan in Karaf was easy, we did write two OSGi Bundles to form a cluster with two nodes that run on one host. We tried it with the tutorial for a distributed cache from the Infinispan website (tutorial). Unfortunately the cluster seems not to be build and we can't determine why. Any help or push in the right direction would be very appreciated.
The code of the bundle that writes something in the cache looks like that:
import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.context.Flag;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CacheProducer implements BundleActivator{
private static Logger LOG = LoggerFactory.getLogger(CacheProducer.class );
private static DefaultCacheManager cacheManager;
#Override
public void start( BundleContext context ) throws Exception{
LOG.info( "Start Producer" );
GlobalConfigurationBuilder global = GlobalConfigurationBuilder.defaultClusteredBuilder();
global.transport().clusterName("ClusterTest");
// Make the default cache a distributed synchronous one
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.clustering().cacheMode(CacheMode.DIST_SYNC);
// Initialize the cache manager
cacheManager = new DefaultCacheManager(global.build(), builder.build());
// Obtain the default cache
Cache<String, String> cache = cacheManager.getCache();
cache.put( "message", "Hello World!" );
LOG.info( "Producer: whole cluster content!" );
cache.entrySet().forEach(entry -> LOG.info(entry.getKey()+ ": " + entry.getValue()));
LOG.info( "Producer: current cache content!" );
cache.getAdvancedCache().withFlags(Flag.SKIP_REMOTE_LOOKUP)
.entrySet().forEach(entry -> LOG.info(entry.getKey()+ ": " + entry.getValue()));
}
#Override
public void stop( BundleContext context ) throws Exception{
cacheManager.stop();
}
}
And the one that tries to print out what is in the cache like that:
package metdoc81.listener;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.infinispan.Cache;
import org.infinispan.manager.DefaultCacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Activator implements BundleActivator{
private static Logger LOG = LoggerFactory.getLogger(Activator.class);
private static DefaultCacheManager cacheManager;
public void start( BundleContext bundleContext ) throws Exception{
LOG.info("start cluster listener");
GlobalConfigurationBuilder global = GlobalConfigurationBuilder.defaultClusteredBuilder();
global.transport().clusterName("ClusterTest");
// Make the default cache a distributed synchronous one
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.clustering().cacheMode(CacheMode.DIST_SYNC);
// Initialize the cache manager
cacheManager = new DefaultCacheManager(global.build(), builder.build());
// Obtain the default cache
Cache<String, String> cache = cacheManager.getCache();
LOG.info("After configuration");
cache.entrySet().forEach(entry -> LOG.info(entry.getKey()+ ": " + entry.getValue()));
LOG.info("After logging");
}
public void stop( BundleContext bundleContext ) throws Exception{
}
}
The printing from the CacheProducer works, printing from the Listener does not.
We found the solution ourselves.
The problem just occurs when you try to run the code on MacOS, on Windows it's working. According to a discussion at JBossDeveloper there was a problem with the multicast routing on MacOS. Even though they added a workaround into the example code, you still have to add the -Djava.net.preferIPv4Stack=true Flag when running it or you have to add these two lines of code:
Properties properties = System.getProperties();
properties.setProperty( "java.net.preferIPv4Stack", "true" );

What does the EndpointsServlet class do in Google's Endpoints?

First, I am a beginner in java servlets, maven projects and apis.
I am doing the following tutorial on getting started with google endpoints, which is a tutorial implementing the following maven project source code on github. On the web.xml, there is only one named Servlet, the EndpointsServlet like so:
<!-- wrap the backend with Endpoints Framework v2. -->
<servlet>
<servlet-name>EndpointsServlet</servlet-name>
<servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>com.example.echo.Echo</param-value>
</init-param>
</servlet>
What I dont understand is why are there no other servlets on the project? There are only 3 java classes in the main directory and none of them are servlet files. I am assuming that this project is a sample api with server side logic (such as routing and responding to requests) like any other servlet project which means there should be more than this servlet.
The comment on the web.xml is an obvious clue as to what it does but I dont really know what wrapping the backend with endpoints framework means. Also, I actually got the EndpointsServlet.java file and it says the servlet is a "handler for proxy-less API serving. This servlet understands and replies in JSON-REST. Again, I dont really understand this comment nor what the servlet does even reading it. Servlet code below:
package com.google.api.server.spi;
import com.google.api.server.spi.SystemService.EndpointNode;
import com.google.api.server.spi.config.ApiConfigException;
import com.google.api.server.spi.config.model.ApiClassConfig.MethodConfigMap;
import com.google.api.server.spi.config.model.ApiConfig;
import com.google.api.server.spi.config.model.ApiMethodConfig;
import com.google.api.server.spi.dispatcher.PathDispatcher;
import com.google.api.server.spi.handlers.ApiProxyHandler;
import com.google.api.server.spi.handlers.CorsHandler;
import com.google.api.server.spi.handlers.EndpointsMethodHandler;
import com.google.api.server.spi.handlers.ExplorerHandler;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.Map.Entry;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* A handler for proxy-less API serving. This servlet understands and replies in JSON-REST.
*/
public class EndpointsServlet extends HttpServlet {
private static final String EXPLORER_PATH = "explorer";
private ServletInitializationParameters initParameters;
private SystemService systemService;
private PathDispatcher<EndpointsContext> dispatcher;
private CorsHandler corsHandler;
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ClassLoader classLoader = getClass().getClassLoader();
this.initParameters = ServletInitializationParameters.fromServletConfig(config, classLoader);
this.systemService = createSystemService(classLoader, initParameters);
this.dispatcher = createDispatcher();
this.corsHandler = new CorsHandler();
}
#Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
String method = getRequestMethod(request);
if ("OPTIONS".equals(method)) {
corsHandler.handle(request, response);
} else {
String path = Strings.stripSlash(
request.getRequestURI().substring(request.getServletPath().length()));
EndpointsContext context = new EndpointsContext(method, path, request, response,
initParameters.isPrettyPrintEnabled());
if (!dispatcher.dispatch(method, path, context)) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().append("Not Found");
}
}
}
private String getRequestMethod(HttpServletRequest request) {
Enumeration headerNames = request.getHeaderNames();
String methodOverride = null;
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
if (headerName.toLowerCase().equals("x-http-method-override")) {
methodOverride = request.getHeader(headerName);
break;
}
}
return methodOverride != null ? methodOverride.toUpperCase() : request.getMethod();
}
private PathDispatcher<EndpointsContext> createDispatcher() {
PathDispatcher.Builder<EndpointsContext> builder = PathDispatcher.builder();
List<EndpointNode> endpoints = systemService.getEndpoints();
// We're building an ImmutableList here, because it will eventually be used for JSON-RPC.
ImmutableList.Builder<EndpointsMethodHandler> handlersBuilder = ImmutableList.builder();
for (EndpointNode endpoint : endpoints) {
ApiConfig apiConfig = endpoint.getConfig();
MethodConfigMap methods = apiConfig.getApiClassConfig().getMethods();
for (Entry<EndpointMethod, ApiMethodConfig> methodEntry : methods.entrySet()) {
if (!methodEntry.getValue().isIgnored()) {
handlersBuilder.add(
new EndpointsMethodHandler(initParameters, getServletContext(), methodEntry.getKey(),
apiConfig, methodEntry.getValue(), systemService));
}
}
}
ImmutableList<EndpointsMethodHandler> handlers = handlersBuilder.build();
for (EndpointsMethodHandler handler : handlers) {
builder.add(handler.getRestMethod(), Strings.stripTrailingSlash(handler.getRestPath()),
handler.getRestHandler());
}
ExplorerHandler explorerHandler = new ExplorerHandler();
builder.add("GET", EXPLORER_PATH, explorerHandler);
builder.add("GET", EXPLORER_PATH + "/", explorerHandler);
builder.add("GET", "static/proxy.html", new ApiProxyHandler());
return builder.build();
}
private SystemService createSystemService(ClassLoader classLoader,
ServletInitializationParameters initParameters) throws ServletException {
try {
SystemService.Builder builder = SystemService.builder()
.withDefaults(classLoader)
.setStandardConfigLoader(classLoader)
.setIllegalArgumentIsBackendError(initParameters.isIllegalArgumentBackendError())
.setDiscoveryServiceEnabled(true);
for (Class<?> serviceClass : initParameters.getServiceClasses()) {
builder.addService(serviceClass, createService(serviceClass));
}
return builder.build();
} catch (ApiConfigException | ClassNotFoundException e) {
throw new ServletException(e);
}
}
/**
* Creates a new instance of the specified service class.
*
* #param serviceClass the class of the service to create
*/
protected <T> T createService(Class<T> serviceClass) {
try {
return serviceClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(
String.format("Cannot instantiate service class: %s", serviceClass.getName()), e);
} catch (IllegalAccessException e) {
throw new RuntimeException(
String.format("Cannot access service class: %s", serviceClass.getName()), e);
}
}
}
EndpointsServlet handles all API calls with a certain path prefix. It takes a RESTful API call and translates it into POJO(s) and dispatches it to a Java method you've written, and then serializes the return value of that method to JSON. It does this based on how you annotate your code.

Firebase - Keep user logged in when they close app [duplicate]

Thank to Firebase the user can logged with the help of G+, Facebook or Twitter. When they are logged, everything is fine.
When the Android app is closed and re-opened, how to reenable the previous succeed logged user with the Firebase API. It is not explained neither in the app demo or in the documentation.
For exemple for Facebook, the sdk seems to save the token, that 's why the button is at connected state (showing that you can disconnect). But what about Firebase and for other authentication systems.
Thanks to the #Frank-van-Puffelen answer, I had some trials until I get something relevant (at least for me : comment are welcome to improve).
I have based my OAuth architecture into 3 mains components :
fdsfds
One single AuthStateListener that is located in the Application.
One Utils Singleton OAuthManager that deal with all authentication process
One or Many Activities that deals with Authentification user interaction (Signin Buttons and so on)
Application Class
FacebookSdk.sdkInitialize(this);
Firebase.setAndroidContext(this);
Firebase.getDefaultConfig().setLogLevel(Logger.Level.DEBUG);
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
// create a partialUser from authData
OAuthManager.getDefault().setAuthenticatedUser(authData);
// fetch, merge and save back the partialUser with server registerUser.
OAuthManager.getDefault().startFetchingUserInfo();
} else {
// user is not logged in
// Try to retrieve the user from Facebook SDK
// Try to retrieve the user from "Token and Id save in Android Preferences (in case of issue, or cache reset from Firebase))
// In retrieve is not possible, clean auth data
OAuthManager.getDefault().retrieveOAuth(MilleZimU.getInstance());
}
}
});
OAuthManager
Here is every services that deal with authentication (part has been copy from the Firebase dedicated demo activity)
SignInActivity
Here only remain the part that deal with UI interaction.
Retreiving ?
I'm not sure this is necessary, but case to case (maybe due to crash or update of the app), authentication status where different from Firebase|Prefs|FacebookSdk. I will see with time.
You'll need to add a AuthStateListener. This is described in the Firebase documentation on Monitoring Authentication. From there:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
} else {
// user is not logged in
}
}
});
For anything related to Firebase Authentication on Android, the dedicated demo app is a great next stop. But be sure to first read the documentation, they're not half bad as far as docs go.
Create a BaseActivity class and make sure all other Activities in the app extends that class. The use 'instanceOf' to send user to LoginActivity if authData is null from AuthListener.
package com.mabiri.mabiristores;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.firebase.client.AuthData;
import com.firebase.client.Firebase;
import com.mabiri.mabiristores.login.CreateAccount2Activity;
import com.mabiri.mabiristores.login.CreateAccountActivity;
import com.mabiri.mabiristores.login.LoginActivity;
import com.mabiri.mabiristores.login.MapsActivity;
import com.mabiri.mabiristores.utils.Utils;
public class BaseActivity extends AppCompatActivity {
protected Firebase.AuthStateListener mAuthListener;
protected Firebase mFirebaseRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseRef = new Firebase(YOUR_FIREBASE_URL);
if (!((this instanceof LoginActivity) || (this instanceof CreateAccountActivity)
|| (this instanceof CreateAccount2Activity) || (this instanceof MapsActivity))) {
mAuthListener = new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
/* The user has been logged out */
if (authData == null) {
//Stop services and clear sharedPreferences if any
/*Take user to login screen*/
takeUserToLoginScreenOnUnAuth();
}
}
};
mFirebaseRef.addAuthStateListener(mAuthListener);
}
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.menu_base, menu);
return true;
}
private void takeUserToLoginScreenOnUnAuth() {
/** Move user to LoginActivity, and remove the backstack */
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
protected void logout() {
/**Unauthenticate user from firebase*/
mFirebaseRef.unauth();
}
/**
* Show error toast to users
*/
protected void showErrorToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
Yup I have struggle with this as well, but a quick update on this issue, you cannot use the (and please correct me if i'm wrong):
Firebase ref
anymore, what you should do is declare as a global
private FirebaseAuth mAuth;
and then use this object on the listener:
mAuth = FirebaseAuth.getInstance();
and only after that you can use the listener
mAuth.addAuthStateListener(mAuthListener);

How can a native Servlet Filter be used when using Spark web framework?

I'm playing around with Spark (the Java web framework, not Apache Spark).
I find it really nice and easy to define routes and filters, however I'm looking to apply a native servlet filter to my routes and can't seem to find a way to do that.
More specifically, I would like to use Jetty's DoSFilter which is a servlet filter (contrast with the Spark Filter definition). Since Spark is using embedded Jetty, I don't have a web.xml to register the DoSFilter. However, Spark doesn't expose the server instance so I can't find an elegant way of registering the filter programatically either.
Is there a way to apply a native servlet filter to my routes?
I thought of wrapping the DoSFilter in my own Spark Filter, but it seemed like a weird idea.
You can do it like this:
public class App {
private static Logger LOG = LoggerFactory.getLogger(App.class);
public static void main(String[] args) throws Exception {
ServletContextHandler mainHandler = new ServletContextHandler();
mainHandler.setContextPath("/base/path");
Stream.of(
new FilterHolder(new MyServletFilter()),
new FilterHolder(new SparkFilter()) {{
this.setInitParameter("applicationClass", SparkApp.class.getName());
}}
).forEach(h -> mainHandler.addFilter(h, "*", null));
GzipHandler compression = new GzipHandler();
compression.setIncludedMethods("GET");
compression.setMinGzipSize(512);
compression.setHandler(mainHandler);
Server server = new Server(new ExecutorThreadPool(new ThreadPoolExecutor(10,200,60000,TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(200),
new CustomizableThreadFactory("jetty-pool-"))));
final ServerConnector serverConnector = new ServerConnector(server);
serverConnector.setPort(9290);
server.setConnectors(new Connector[] { serverConnector });
server.setHandler(compression);
server.start();
hookToShutdownEvents(server);
server.join();
}
private static void hookToShutdownEvents(final Server server) {
LOG.debug("Hooking to JVM shutdown events");
server.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() {
#Override
public void lifeCycleStopped(LifeCycle event) {
LOG.info("Jetty Server has been stopped");
super.lifeCycleStopped(event);
}
});
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
LOG.info("About to stop Jetty Server due to JVM shutdown");
try {
server.stop();
} catch (Exception e) {
LOG.error("Could not stop Jetty Server properly", e);
}
}
});
}
/**
* #implNote {#link SparkFilter} needs to access a public class
*/
#SuppressWarnings("WeakerAccess")
public static class SparkApp implements SparkApplication {
#Override
public void init() {
System.setProperty("spring.profiles.active", ApplicationProfile.readProfilesOrDefault("dev").stream().collect(Collectors.joining()));
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ModocContext.class);
ctx.registerShutdownHook();
}
}}

Resources