在Android中为ResourceBundle.getBundle(String path)放置资源的位置?

时间:2015-05-18 11:27:29

标签: android android-resources

我在我的android项目中使用了一个ee-jar。它使用$(function() { $("#tabs").tabs(); $(document).on('click', '#rebuild', function() { var ul = $('#tabs').find('ul'); var liElement1 = $('<li />'); $(liElement1).append('<a href="#tab1" >tab1</a>'); var liElement2 = $('<li />'); $(liElement2).append('<a href="#tab2" >tab2</a>'); $(ul).append(liElement1); $(ul).append(liElement2); $("#tabs").append('<div id="tab1"><p>sample1</p></div><div id="tab2"><p>.</p><p>Sample2</p></div>'); $("#tabs").tabs("refresh"); }); }); 表示i18n。由于资源在jar中被剥离而且.apk不包含资源而且我得到一个例外:

ResourceBundle.getBundle(String path)

为了解决这个问题,我该怎么办?我的想法是从jar获取资源并将它们放入Android项目的资源文件夹中。它的正确位置在哪里? Android确实支持java.util.MissingResourceException: Can't find resource for bundle 'org/apache/xml/security/resource/xmlsecurity_en_US', key '' at java.util.ResourceBundle.missingResourceException(ResourceBundle.java:239) at java.util.ResourceBundle.getBundle(ResourceBundle.java:231) at org.apache.wss4j.common.crypto.WSS4JResourceBundle.<init>(WSS4JResourceBundle.java:54) at org.apache.wss4j.common.crypto.WSProviderConfig.initializeResourceBundles(WSProviderConfig.java:199) at org.apache.wss4j.common.crypto.WSProviderConfig.init(WSProviderConfig.java:65) at org.apache.wss4j.dom.WSSConfig.init(WSSConfig.java:428) at org.apache.wss4j.dom.WSSConfig.getNewInstance(WSSConfig.java:435) at org.apache.wss4j.dom.WSSecurityEngine.getWssConfig(WSSecurityEngine.java:148) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:215) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:190) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:96) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122) at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243) at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:261) at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1088) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1024) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:370) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494) at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543) at java.lang.Thread.run(Thread.java:841) reference),但没有写入放置资源的位置。

1 个答案:

答案 0 :(得分:0)

我必须:

  1. 介绍资源加载器接口(WSS4JResourceBundle.ResourceBundleLoader
  2. 引入静态资源加载器变量来加载资源(public static ResourceBundleLoader sharedLoader
  3. 使用ResourceBundle.getBundle将加载资源替换为静态var方法调用(wss4jSecResourceBundle = sharedLoader.getBundle("messages.wss4j_errors"); f.e。)
  4. 创建默认(DefaultResourceBundleLoader)和Android实现(AndroidResourceBundleLoader
  5. 将资源重新打包到android的项目assets文件夹
  6. 在app launch(WSS4JResourceBundle.sharedLoader = new AndroidResourceBundleLoader(ctx, "wss4j/");
  7. 上注入android impl而不是默认值

    已修改 WSS4JResourceBundle

    package org.apache.wss4j.common.crypto;
    
    import java.util.Enumeration;
    import java.util.Locale;
    import java.util.MissingResourceException;
    import java.util.ResourceBundle;
    
    import org.apache.xml.security.utils.Constants;
    import org.apache.xml.security.utils.I18n;
    
    /**
     * ResourceBundle for WSS4J
     */
    public class WSS4JResourceBundle extends ResourceBundle {
    
        /**
         * Loader API
         */
        public interface ResourceBundleLoader {
            ResourceBundle getBundle(String path);
            ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader);
        }
    
        // default
        public static ResourceBundleLoader sharedLoader = new DefaultResourceBundleLoader();
    
        /**
         * Default IMPL
         */
        public static class DefaultResourceBundleLoader implements ResourceBundleLoader {
            @Override
            public ResourceBundle getBundle(String path) {
                return ResourceBundle.getBundle(path);
            }
    
            @Override
            public ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader) {
                return ResourceBundle.getBundle(baseName, locale, loader);
            }
        }
    
        private static final org.slf4j.Logger LOG = 
            org.slf4j.LoggerFactory.getLogger(WSS4JResourceBundle.class);
    
        private final ResourceBundle wss4jSecResourceBundle;
        private final ResourceBundle xmlSecResourceBundle;
    
        public WSS4JResourceBundle() {
            wss4jSecResourceBundle = sharedLoader.getBundle("messages.wss4j_errors");
    
            ResourceBundle tmpResourceBundle;
            try {
                tmpResourceBundle = sharedLoader.getBundle(
                            Constants.exceptionMessagesResourceBundleBase,
                            Locale.getDefault(),
                            I18n.class.getClassLoader());
            } catch (MissingResourceException ex) {
                // Using a Locale of which there is no properties file.
                LOG.debug(ex.getMessage());
                // Default to en/US
                tmpResourceBundle =
                        sharedLoader.getBundle(Constants.exceptionMessagesResourceBundleBase,
                                             new Locale("en", "US"), I18n.class.getClassLoader());
            }
            xmlSecResourceBundle = tmpResourceBundle;
        }
    
        @Override
        protected Object handleGetObject(String key) {
            Object value = null;
            try {
                value = wss4jSecResourceBundle.getObject(key);
            } catch (MissingResourceException e) {
                try {
                    value = xmlSecResourceBundle.getObject(key);
                } catch (MissingResourceException ex) { //NOPMD
                    //ignore
                }
            }
            return value;
        }
    
        @Override
        public Enumeration<String> getKeys() {
            throw new UnsupportedOperationException("getKeys not supported");
        }
    
    }
    

    AndroidResourceBundleLoader

    package org.apache.wss4j.common.crypto;
    
    import android.content.Context;
    import android.content.res.AssetManager;
    import com.splinex.streaming.Log;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Locale;
    import java.util.PropertyResourceBundle;
    import java.util.ResourceBundle;
    
    public class AndroidResourceBundleLoader implements WSS4JResourceBundle.ResourceBundleLoader {
    
        private static final String TAG = AndroidResourceBundleLoader.class.getSimpleName();
    
        private String prefix;
        private AssetManager manager;
    
        public AndroidResourceBundleLoader(Context context, String prefix) {
            manager = context.getAssets();
            this.prefix = prefix;
        }
    
        @Override
        public ResourceBundle getBundle(String path) {
            try {
                String fullPath = prefix + path.replace(".", "/") + ".properties";
                return new PropertyResourceBundle(manager.open(fullPath));
            } catch (IOException e) {
                android.util.Log.e(TAG, "Failed to load " + path, e);
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public ResourceBundle getBundle(String path, Locale locale, ClassLoader classLoader) {
            return getBundle(path + "_" + locale.getLanguage());
        }
    }
    

    像这样注入android impl:

    WSS4JResourceBundle.sharedLoader = new AndroidResourceBundleLoader(ctx, "wss4j/");