Helyfüggetlen hozzáférés az erőforrásokhoz

  • Áttekintés
  • Források, nevek és kontextusok
  • Rendszeres erőforrások
  • Nem rendszeres erőforrások
  • Forrásnevek
  • Using Methods of java.lang.Class
  • Using Methods ofjava.lang.ClassLoader
  • Security
  • Examples

Overview

A forrás olyan adat (kép, hang, szöveg stb.), amelyet egy programnak a programkód helyétől független módon kell elérnie. A Java programok két mechanizmust használhatnakaz erőforrások eléréséhez: Az appletek a Applet.getCodeBase()t használják az appletkód alap-URL-jének megadására, majd az alap-URL-t egy relatív elérési úttal bővítik a kívánt erőforrás betöltéséhez, például a Applet.getAudioClip(url)-vel. Az alkalmazások “jól ismert helyeket” használnak, mint példáulSystem.getProperty("user.home") vagySystem.getProperty("java.home"), majd hozzáadják a”/lib/resource”-t, és megnyitják ezt a fájlt.

A Class ésClassLoader osztályok metódusai egy helyfüggetlen módot biztosítanak az erőforrások betöltésére. Például lehetővé teszik az erőforrások megtalálását:

  • Az internetről több HTTPkapcsolat segítségével betöltött applet.
  • A JAR fájlok segítségével betöltött applet.
  • A CLASSPATH-ba betöltött vagy telepített Java Bean.
  • A CLASSPATH-ba telepített “könyvtár”.

Ezek a módszerek nem nyújtanak külön támogatást a lokalizált erőforrások megtalálására. A lokalizált erőforrásokat a nemzetköziesítési lehetőségek támogatják.

Források, nevek és kontextusok

A forrást egy olyan karakterlánc azonosítja, amely egy sor alsztringből áll, amelyet ferdehúzás (/) határol, majd az erőforrás neve követ.Minden alsztringnek érvényes Java azonosítónak kell lennie. Az erőforrás neve shortName vagy shortName.extension alakú. AshortName és a extension is Java azonosítónak kell lennie.

Az erőforrás neve független a Java-implementációtól; különösen, hogy az útvonalválasztó mindig ferde (/). Azonban a Java implementáció szabályozza annak részleteit, hogy az erőforrás tartalma hogyan képződik le egy fájlba, adatbázisba vagy más, a tényleges erőforrást tartalmazó objektumba.

Az erőforrás nevének értelmezése relatív az osztálybetöltő példányához. AClassLoader osztály által implementált metódusok végzik ezt az értelmezést.

Rendszer erőforrás

A rendszer erőforrás olyan erőforrás, amely vagy a rendszerbe van beépítve, vagy amelyet a hoszt implementáció tart például egy helyi fájlrendszerben. A programok aClassLoader getSystemResource ésgetSystemResourceAsStream metódusokon keresztül érik el a rendszererőforrásokat.

Egy adott implementációban például egy rendszererőforrás megtalálása magában foglalhatja a CLASSPATH bejegyzéseiben való keresést. AClassLoader metódusok a CLASSPATH minden egyes könyvtár, ZIP fájl vagy JAR fájl bejegyzését átkutatják az erőforrás fájl után, és ha megtalálják, akkor vagy egy InputStream, vagy az erőforrás nevét adják vissza. Ha nem találják, a metódusok nullát adnak vissza. Az erőforrás a CLASSPATH más bejegyzésében is megtalálható, mint ahová az osztályfájlt betöltötték.

Non-System Resources

A getResource végrehajtása egy osztály betöltésénél a ClassLoader osztály részleteitől függ. Például AppletClassLoader:

  • Először megpróbálja megtalálni az erőforrást rendszererőforrásként; majd,ha nem találja,
  • Keres az ebben a CODEBASE-ben már betöltött archívumokban (JAR fájlok) lévő erőforrások között; majd,ha nem találja,
  • A CODEBASE-t használja és megpróbálja megtalálni az erőforrást (ami egy távoli helyszínnel való kapcsolatfelvételt jelenthet).

Minden osztálybetöltő először rendszerforrásként keresi az erőforrást, az osztályfájlok kereséséhez hasonló módon. Ez a keresési szabály lehetővé teszi bármely erőforrás helyi felülírását. Az ügyfeleknek olyan erőforrásnevet kell választaniuk, amely egyedi lesz (például a cég- vagy csomagnevet használva előtagként).

Az erőforrásnevek

Az osztály által használt erőforrás nevére vonatkozó általános konvenció az, hogy az osztály csomagjának teljes minősítésű nevét használják, de az összes pontot (.) átváltoztatják perjelre (/), és hozzáadnak egy name.extension formájú erőforrásnevet. Ennek támogatására, valamint a rendszerosztályok (amelyek esetében agetClassLoader nullát ad vissza) részleteinek egyszerűbb kezelése érdekében az osztályClass két kényelmi metódust biztosít, amelyek meghívják a ClassLoader megfelelő metódusait.

A Class metódusnak adott erőforrásnévnek lehet egy “/” kezdőbetűje, amely “abszolút” névként azonosítja.Az olyan erőforrásnevek, amelyek nem kezdődnek “/”-vel, “relatívak”.

Az abszolút nevekből eltávolítjuk a kezdő “/”-t, és minden további módosítás nélkül átadjuk a megfelelőClassLoader metódusnak az erőforrás megtalálására. A relatív neveket a korábban ismertetett konvenció szerint módosítjuk, majd átadjuk egy ClassLoader metódusnak.

Using Methods of java.lang.Class

A Class osztály több metódust is implementál az erőforrások betöltésére.

A getResource() metódus visszaadja az erőforrás URL-jét. Az URL (és annak reprezentációja) az implementációra és a JVM-re jellemző (vagyis az egyik futásidejű példányban kapott URL nem biztos, hogy egy másikban működik). A protokollja általában az erőforrást betöltő ClassLoader-ra jellemző. Haaz erőforrás nem létezik vagy biztonsági megfontolások miatt nem látható, a metódusok nullát adnak vissza.

Ha a klienskód az erőforrás tartalmát InputStreamként akarja olvasni, akkor az URL-re alkalmazhatja aopenStream() metódust. Ez elég gyakori ahhoz, hogy indokolja a getResourceAsStream() hozzáadását aClass-hoz és a ClassLoader-hoz. ugyanaz, mint agetResource().openStream() hívása, kivéve, hogy agetResourceAsStream() az IO kivételeket elkapja, és egy null InputStream-t ad vissza.

A klienskód az erőforrás tartalmát objektumként is kérheti a java.net.URL.getContent()módszer alkalmazásával az URL-en. Ez akkor hasznos, ha az erőforrás például egy kép adatait tartalmazza. Kép esetén az eredmény egy awt.image.ImageProducer objektum, nem pedig egyImage objektum.

A getResource és getResourceAsStream metódusok egy adott nevű erőforrást keresnek. Null értéket adnak vissza, ha nem találnak erőforrást a megadott névvel. Az adott osztályhoz tartozó erőforrások keresésének szabályait az osztályClassLoader-je hajtja végre. A Class metódusok aClassLoader metódusokhoz delegálnak, miután egy névadási konvenciót alkalmaztak: ha az erőforrás neve “/”-vel kezdődik, akkor úgy használjuk, ahogy van.Ellenkező esetben a csomag neve előtagot kap, miután az összes pontot (.) átváltoztattuk kötőjelekké (/).

public InputStream getResourceAsStream(String name) { name = resolveName(name); ClassLoader cl = getClassLoader(); if (cl==null) { return ClassLoader.getSystemResourceAsStream(name); // A system class. } return cl.getResourceAsStream(name);}public java.net.URL getResource(String name) { name = resolveName(name); ClassLoader cl = getClassLoader(); if (cl==null) { return ClassLoader.getSystemResource(name); // A system class. } return cl.getResource(name);}

A resolveName metódus hozzáad egy csomagnév előtagot, ha a név nem abszolút, és eltávolítja a vezető “/”-t, ha a név abszolút. Lehetséges, bár nem gyakori, hogy különböző csomagokban lévő osztályok ugyanazt az erőforrást használják.

private String resolveName(String name) { if (name == null) { return name; } if (!name.startsWith("/")) { Class c = this; while (c.isArray()) { c = c.getComponentType(); } String baseName = c.getName(); int index = baseName.lastIndexOf('.'); if (index != -1) { name = baseName.substring(0, index).replace('.', '/') + "/" + name; } } else { name = name.substring(1); } return name;}

Using Methods of java.lang.ClassLoader

A ClassLoader osztály kétféle metódussal rendelkezik az erőforrások eléréséhez. Az egyik készlet egy InputStream erőforrást ad vissza. A másik készlet egy URL-t ad vissza. A InputStream-t visszaadó metódusok könnyebben használhatók és sok igényt kielégítenek, míg az URL-t visszaadó metódusok bonyolultabb információkhoz, például egy képhez és egy AudioCliphez biztosítanak hozzáférést.

A ClassLoader az osztályok kezeléséhez hasonlóan kezeli az erőforrásokat. A ClassLoader szabályozza, hogyan kapcsolja össze egy erőforrás nevét annak tartalmával. A ClassLoadera rendszer erőforrásainak eléréséhez is biztosít metódusokat,a rendszerosztályokhoz hasonlóan. A Classosztály biztosít néhány kényelmi metódust, amelyek a funkciókat a ClassLoader metódusokra delegálják.

Minden Java program közvetve, az I18N (lokalizációs) API-kon keresztül éri el ezeket a metódusokat. Mások a Class metódusain keresztül férnek hozzá. Néhányan közvetlenül hívják meg aClassLoader metódusokat.

A ClassLoader metódusok a megadott karakterláncot használják az erőforrás neveként anélkül, hogy abszolút/relatív transzformációt alkalmaznának (lásd a Class metódusokat). A név nem tartalmazhat egy vezető “/” betűt.

A rendszer erőforrásai azok, amelyeket a hosztimplementáció közvetlenül kezel. Például aCLASSPATH-ban találhatók.

Az erőforrás neve egy “/”-vel elválasztott azonosítósorozat. A Class osztály kényelmi módszereket biztosít az erőforrások eléréséhez; a módszerek egy olyan konvenciót valósítanak meg, ahol a csomag neve elé az erőforrás rövid neve kerül.

A források elérhetők InputStream, vagy egyURL formájában.

A getSystemResourceAsStream módszer visszaad egyInputStream-et a megadott rendszererőforráshoz, vagy null, ha nem találja az erőforrást. Az erőforrás neve bármilyen rendszerforrás lehet.

A getSystemResource módszer megtalálja a megadott nevű rendszerforrást. Visszaadja az erőforrás URL-címét vagy null, ha nem találja az erőforrást. Ajava.net.URL.getContent() meghívása az URL-lel egy objektumot ad vissza, például ImageProducer, AudioClip vagy InputStream.

A getResourceAsStream módszer egyInputStream-t ad vissza a megadott erőforráshoz vagy nullát, ha nem találja az erőforrást.

A getResource módszer egy erőforrást talál a megadott névvel. Visszaadja az erőforrás URL-címét, vagy null, ha nem találja az erőforrást. Ajava.net.URL.getContent() meghívása az URL-lel egy olyan objektumot ad vissza, mint ImageProducer, AudioClip vagy InputStream.

Biztonság

Mivel a getResource() hozzáférést biztosít az információkhoz,jól meghatározott és megalapozott biztonsági szabályokkal kell rendelkeznie. Ha a biztonsági megfontolások nem teszik lehetővé, hogy egy erőforrás látható legyen valamilyen biztonsági kontextusban, a getResource() metódus sikertelen lesz (nullát ad vissza), mintha az erőforrás egyáltalán nem lenne jelen, eza létezési támadásokat kezeli.

Az osztálybetöltők nem biztosíthatnak hozzáférést egy .classfile tartalmához, mind biztonsági, mind teljesítménybeli okokból. Az, hogy lehetséges-e URL-t kapni egy .class fájlhoz, az alábbiakban bemutatottak szerint a sajátosságoktól függ.

Nincsenek meghatározott biztonsági problémák vagy korlátozások a nem rendszer osztálybetöltő által talált erőforrásokkal kapcsolatban.A AppletClassLoader hozzáférést biztosít a forráshelyről betöltött információkhoz, akár egyenként, akár egy JAR-fájlon keresztül csoportosan; így a AppletClassLoadernek ugyanazokat a checkConnect() szabályokat kell alkalmaznia, amikor az URL-eket a getResource()-n keresztül kezeli.

A rendszer ClassLoader hozzáférést biztosít a CLASSPATH-ban lévő információkhoz. A CLASSPATH tartalmazhat könyvtárakat és JAR fájlokat. Mivel egy JAR-fájlt szándékosan hozunk létre, más jelentősége van, mint egy könyvtárnak, ahol a dolgok véletlenszerűbben véget érhetnek. Különösen szigorúbbak vagyunk abban, hogy egy könyvtárból információt kapjunk, mint egy JAR-fájlból.

Ha egy erőforrás egy könyvtárban van:

  • getResource() a meghívások aFile.exists() segítségével határozzák meg, hogy a megfelelő fájlt láthatóvá tegyék-e a felhasználó számára. Emlékezzünk arra, hogy aFile.exists() a checkRead() metódust használja a biztonsági kezelőben.
  • ugyanez vonatkozik a getResourceAsStream()-ra.

Ha az erőforrás egy JAR fájlban van:

  • getResource() a meghívás minden fájl esetében sikeres lesz, függetlenül attól, hogy a meghívás egy rendszeren belüli vagy egy nem rendszeren belüli osztályból történik.
  • getResourceAsStream() a meghívások sikeresek lesznek a nem .class erőforrások esetében, és így ajava.net.URL.getContent() megfelelő URL-eken is.

Példák

Ez a szakasz két példát mutat be az ügyfélkódra. Az első példa “abszolút erőforrásneveket” és hagyományos mechanizmusokat használ egy Class objektum kinyeréséhez.

package pkg;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;class Test { private static final String absName = "/pkg/mumble.baf"; public static void test1() { Class c=null; try { c = Class.forName("pkg.Test"); } catch (Exception ex) { // This should not happen. } InputStream s = c.getResourceAsStream(absName); // do something with it. } public void test2() { InputStream s = this.getClass().getResourceAsStream(absName); // do something with it. }}

Ez a példa “relatív erőforrásneveket” és a fordító által a -experimentaljelzőn keresztül elérhető mechanizmust használja egy Class objektum kinyeréséhez.

package pkg;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;class Test { private static final String relName = "mumble.baf"; public static void test1() { InputStream s = Test.class.getResourceAsStream(relName); // do something with it.} public void test2() { InputStream s = Test.class.getResourceAsStream(relName); // do something with it. }

.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.