أي طرق ذكية للتعامل مع السياق في شبكة التطبيق ؟

StackOverflow https://stackoverflow.com/questions/125359

سؤال

في جاوة ، تطبيقات الويب هي واحدة في الحروب.افتراضي العديد من الحاويات بريمج استخدام الحرب اسم السياق اسم التطبيق.

وهكذا myapp.الحرب يحصل على نشرها http://example.com/myapp.

المشكلة هي أن webapp تعتبر "الجذر" أن يكون حسنا "الجذر" أو ببساطة "/", في حين HTML ستنظر في جذر التطبيق الخاص بك أن تكون "/myapp".

بريمج API و JSP مرافق للمساعدة في إدارة هذا.على سبيل المثال ، إذا ، في بريمج, يمكنك القيام به:استجابة.sendRedirect("/mypage.التخطيط الاستراتيجي المشترك") ، فإن الحاوية prepend سياق وخلق url: http://example.com/myapp/mypage.jsp".

ومع ذلك لا يمكنك أن تفعل هذا مع العلامة IMG في HTML.إذا قمت بذلك <img src="/myimage.gif" /> سوف تحصل على الأرجح 404 ، لأن ما كنت تريد حقا كان "/myapp/myimage.gif".

العديد من أطر التخطيط الاستراتيجي المشترك العلامات التي السياق علم كذلك, و هناك طرق مختلفة لجعل عناوين url الصحيحة داخل JSP (لا سيما بأناقة).

انها تفاصيل المشكلة المبرمجون على القفز في الخروج من عند استخدام "التطبيق النسبي" url مقابل url المطلق.

وأخيرا ، هناك مسألة من شفرة جافا سكريبت التي تحتاج إلى إنشاء عناوين url على الطاير, جزءا لا يتجزأ من عناوين المواقع داخل CSS (على خلفية الصور وما شابه).

أنا الغريب ما تقنيات استخدام الآخرين للتخفيف يعمل حول هذه المسألة.العديد من ببساطة بونت و رمز القرص الثابت ، إما إلى خادم الجذر أو إلى اختلاف السياق الذي يحدث ليكون باستخدام.أعرف مسبقا أن الجواب ليس هذا ما أنا أبحث عنه.

ماذا تفعل ؟

هل كانت مفيدة؟

المحلول

يمكنك استخدام JSTL إنشاء عناوين url.

على سبيل المثال ، <c:url value="/images/header.jpg" /> سوف البادئة سياق الجذر.

مع CSS, هذه عادة ليست مشكلة بالنسبة لي.

لدي ويب الجذر هيكل من هذا القبيل:

/css
/الصور

في ملف CSS, ثم تحتاج فقط إلى استخدام عناوين url النسبية (../images/header.jpg) وأنها لا تحتاج إلى أن تكون على علم من سياق الجذر.

أما بالنسبة جافا سكريبت ، ما يعمل بالنسبة لي هو بما في ذلك بعض جافا سكريبت العامة في رأس الصفحة مثل هذه:

<script type="text/javascript">
var CONTEXT_ROOT = '<%= request.getContextPath() %>';
</script>

ثم يمكنك استخدام سياق الجذرية في كافة البرامج النصية الخاصة بك (أو يمكنك تحديد وظيفة لبناء مسارات - قد يكون قليلا أكثر مرونة).

ومن الواضح أن كل هذا يعتمد على الخاص بك باستخدام ملفات jsp و JSTL ، ولكن يمكنني استخدام JSF مع Facelets و التقنيات المستخدمة متشابهة - الفرق الحقيقي الوحيد هو الحصول على سياق الجذرية في طريقة مختلفة.

نصائح أخرى

لصفحات HTML, أنا فقط تعيين HTML <base> الوسم.كل ارتباط نسبي (أيليس بدءا من مخطط أو /) سوف تصبح نسبة إلى ذلك.لا يوجد نظيفة وسيلة للاستيلاء عليها على الفور من قبل HttpServletRequest, لذا نحن بحاجة إلى القليل من المساعدة من JSTL هنا.

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="url">${req.requestURL}</c:set>
<c:set var="uri">${req.requestURI}</c:set>

<!DOCTYPE html>
<html lang="en">
  <head>
    <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
    <link rel="stylesheet" href="css/default.css">
    <script src="js/default.js"></script>
  </head>
  <body>
    <img src="img/logo.png" />
    <a href="other.jsp">link</a>
  </body>
</html>

هذا بدوره ومع ذلك التحذير:المراسي (إن #identifier URL) سوف تصبح نسبة إلى قاعدة مسار كذلك.إذا كان لديك أي منهم ، كنت ترغب في جعل الأمر بالنسبة إلى طلب عنوان (URI) بدلا من ذلك.حتى تغيير مثل

<a href="#identifier">jump</a>

إلى

<a href="${uri}#identifier">jump</a>

في JS, يمكنك فقط الوصول إلى <base> عنصر من دوم كلما كنت ترغب في تحويل URL النسبي إلى المطلق URL.

var base = document.getElementsByTagName("base")[0].href;

أو إذا كنت تفعل مسج

var base = $("base").attr("href");

في CSS, صورة عناوين url النسبية إلى URL الأنماط نفسها.لذا مجرد قطرة الصور في مجلد نسبة إلى الأنماط نفسها.E. g.

/css/style.css
/css/images/foo.png

و مرجع لهم على النحو التالي

background-image: url('images/foo.png');

إذا كنت بدلا من ذلك إلى إسقاط الصور في مجلد في نفس مستوى المجلد المغلق

/css/style.css
/images/foo.png

ثم استخدام ../ إلى الذهاب إلى المجلد الأصل

background-image: url('../images/foo.png');

انظر أيضا:

أنا أتفق مع tardate.لقد دفعت انتباهي في المرشحات جدا و قد وجدت الحل في مواجهة المشروع UrlRewriteFilter.بسيطة التكوين مثل التالية:

<rule>
    <from>^.+/resources/(.*)$</from>
    <to>/resources/$1</to>
</rule>

يساعد على توجيه كافة طلبات */الموارد مسار /الموارد تمر (بما في ذلك سياق مسار البادئة).لذا يمكن ببساطة كل ما عندي الصور و CSS ملفات تحت الموارد المجلد الاستمرار في استخدام عناوين url النسبية في أنماط خلفية الصور وغيرها من الحالات.

بريمج API و JSP لديك مرافق للمساعدة في إدارة هذا.بالنسبة سبيل المثال ، إذا ، في بريمج, يمكنك القيام به:استجابة.sendRedirect("/mypage.jsp"), الحاوية سوف prepend سياق و إنشاء عنوان url: http://example.com/myapp/mypage.jsp".

آه, ربما لا انها تعتمد على الحاوية بريمج المواصفات!

من بريمج 2.3:الميزات الجديدة المكشوفة:

و أخيرا و بعد نقاش مطول من قبل مجموعة من الخبراء ، بريمج API 2.3 وقد أوضحت مرة واحدة وإلى الأبد بالضبط ما يحدث على res.sendRedirect("/index.html") دعوة عن بريمج المنفذة داخل غير الجذر السياق.القضية هي أن بريمج API 2.2 يتطلب غير مكتملة مسار مثل "/index.html" أن تكون ترجمة بريمج الحاويات في المسار الكامل ، ولكن لا نقول كيف سياق معالجة مسارات.إذا كان بريمج إجراء المكالمة في السياق في المسار "/contextpath," ينبغي توجيه URI ترجمة نسبة إلى حاوية الجذر (http://server:port/index.html) أو السياق الجذر (http://server:port/contextpath/index.html)?لأقصى قدر من قابلية انه بد من تحديد السلوك ؛ بعد نقاش طويل ، الخبراء اختار ترجمة النسبي حاوية الجذر.بالنسبة لأولئك الذين يريدون سياق قريب ، يمكنك prepend على الإخراج من getContextPath() الخاص بك URI.

حتى لا مع 2.3 المسارات الخاصة بك هي لا يترجم تلقائيا لتشمل سياق المسار.

لقد استعملت فئات المساعد لتوليد img العلامات إلخ.هذه الفئة المساعد يعتني التقديم مسارات مع التطبيق contextPath.(يعمل هذا, ولكن أنا لا حقا مثل ذلك.إذا كان أي شخص لديه أي بدائل أفضل ، من فضلك قل.)

عن مسارات في ملفات css الخ.يمكنني استخدام النمل بناء السيناريو يستخدم الموقع.إنتاج.css للموقع.css في بيئة الإنتاج و الموقع.التنمية.css في التنمية encironment.

بدلا من ذلك أنا في بعض الأحيان استخدام نملة نصي يستبدل @المميز@ الرموز مع البيانات المناسبة لمختلف environents.في هذه الحالة @contextPAth@ رمزية سيتم استبداله مع السياق الصحيح المسار.

خيار واحد هو استخدام "شقة" تطبيق هيكل عناوين url النسبية كلما كان ذلك ممكنا.

من قبل "شقة" أعني أنه لا توجد الدلائل الفرعية تحت الجذر للتطبيق ، ربما فقط بعض الدلائل على محتوى ثابت مثل "صور/".كل JSP ، عمل عناوين, servlets تذهب مباشرة تحت الجذر.

هذا ليس تماما حل مشكلتك ولكن يبسط إلى حد كبير.

Vilmantas قال كلمة الحق هنا:عناوين url النسبية.

كل ما عليك القيام به في الخاص بك IMG استخدام

<img src="myimage.gif"/>

بدلا من

<img src="/myimage.gif"/>

و ستكون نسبة إلى سياق التطبيق (مثل المتصفح هو تفسير URL الذهاب)

باستثناء حالات خاصة ، أنصح ضد استخدام عناوين url مطلقة بهذه الطريقة.من أي وقت مضى.المطلق عناوين جيدة عندما آخر webapp هو يشير إلى شيء في webapp.داخليا-عندما مورد واحد هو لافتا في المورد الثاني في نفس السياق -- الموارد يجب أن تعرف أين يعيش ، لذلك يجب أن تكون قادرة على التعبير عن مسار نسبي في المورد الثاني.

بالطبع, سوف أكتب وحدات المكونات التي لا تعرف الموارد بما في ذلك لهم.على سبيل المثال:

/myapp/user/email.jsp:
Email: <a href="../sendmail.jsp">${user.email}</a>

/myapp/browse/profile.jsp:
<jsp:include page="../user/email.jsp" />

/myapp/home.jsp:
<jsp:include page="../user/email.jsp" />

كيف email.jsp تعرف المسار النسبي من sendmail.jsp?بوضوح على الرابط سوف كسر على أي /myapp/browse/profile.jsp أو أنها سوف كسر على /myapp/home.jsp .الجواب هو الحفاظ على جميع عناوين المواقع الخاصة بك في نفس شقة أسم دليل الفضائية.هذا هو كل عنوان URL يجب أن لا تخفض بعد /myapp/ .

هذا من السهل جدا لإنجاز طالما لديك نوع من الخرائط بين عناوين المواقع و الملفات الفعلية التي تولد المحتوى.(مثلا ، في الربيع ، استخدام DispatcherServlet إلى خريطة عناوين المواقع إلى ملفات JSP أو وجهات النظر.)

هناك حالات خاصة.على سبيل المثالإذا كنت تكتب في المتصفح جانب التطبيقات في جافا سكريبت ، ثم فإنه يحصل على أكثر صعوبة للحفاظ على شقة أسم دليل الفضائية.في هذه الحالة أو في غيرها من الحالات الخاصة ، أو إذا كان لديك تفضيل شخصي, ليس حقا صفقة كبيرة إلى استخدام <%= request.getContextPath() %> لخلق مسار مطلق.

يمكنك استخدام الطلب.getContextPath() لبناء المطلق عناوين المواقع التي لا ترميز-الثابت سياق محدد.كما رد سابق أشار إلى جافا سكريبت يمكنك فقط تعيين متغير في الجزء العلوي من JSP (أو يفضل أن يكون ذلك في قالب) بادئة حسب السياق.

هذا لا ينفع CSS استبدال صورة إلا إذا كنت تريد بشكل حيوي إنشاء ملف CSS التي يمكن أن يسبب مشاكل أخرى.ولكن منذ كنت تعرف أين ملف CSS هو بالنسبة إلى الصور الخاصة بك ، يمكنك الحصول على بعيدا مع عناوين url النسبية.

لسبب ما كان عندي مشكلة مع أي التعامل مع عناوين url النسبية و كان إلى العودة إلى استخدام التعبيرات مع متغير جافا سكريبت تعيين السياق.أنا فقط تقسيم أي صورة بدائل إيقاف في ملف استخدام أي وحدات الماكرو إلى سحب في الصحيح منها.لم يكن صفقة كبيرة لأنني بالفعل قد فعل ذلك للتعامل مع شفافة PNGs على أي حال.انها ليست جميلة ، لكنه يعمل.

لقد استخدمت معظم هذه التقنيات (حفظ XSLT العمارة).

أعتقد أن جوهر (والإجماع) المشكلة هو وجود موقع يحتمل أن تكون الدلائل متعددة.

إذا الدليل عمق (لعدم وجود مصطلح أفضل) هو ثابت ، ثم يمكنك الاعتماد على عناوين url النسبية في أشياء مثل CSS.

العقل تخطيط لا يجب أن تكون مسطحة تماما, فقط متسقة.

على سبيل المثال, لقد قمنا الهرمية مثل /css /js /مشتركة /admin /المستخدم.وضع الصفحات المناسبة والموارد المناسبة الدلائل.وجود هيكل مثل هذا يعمل بشكل جيد جدا مع الحاويات القائمة على المصادقة.

لقد تعيينها أيضا *.css و *.js إلى JSP بريمج و جعلهم ديناميكية لذا يمكن بناء عليها على الطاير.

كنت أتمنى فقط كان هناك شيء آخر كنت قد غاب.

أنا من قبل لا يعني ادعاء أن يلي أنيقة المسألة.في الواقع, بعد فوات الأوان, أنا لا أوصي هذا الموضوع نظرا (على الأرجح) ضرب الأداء.

التطبيق على شبكة الإنترنت هو JSPs بدقة XML البيانات الخام.هذه البيانات الخام ثم أرسل إلى XSL (server-side) التي تطبق في حق فئة CSS, وبصق XHTML.

لدينا قالب واحد.xsl التي من شأنها أن تكون موروثة من قبل عدة ملفات XSL أننا قد لمكونات مختلفة من الموقع.طرقنا كان كل تعريف في ملف XSL يسمى paths.xml:

<?xml version="1.0" encoding="UTF-8"?>
<paths>
    <path name="account" parent="home">Account/</path>
    <path name="css">css/</path>
    <path name="home">servlet/</path>
    <path name="icons" parent="images">icons/</path>
    <path name="images">images/</path>
    <path name="js">js/</path>
</paths>

وصلة داخلية في XML على النحو التالي:

<ilink name="link to icons" type="icons">link to icons</ilink>

هذا من شأنه أن الحصول على معالجتها من قبل XSL:

<xsl:template match="ilink">
    <xsl:variable name="temp">
        <xsl:value-of select="$rootpath" />
        <xsl:call-template name="paths">
            <xsl:with-param name="path-name"><xsl:value-of select="@type" /></xsl:with-param>
        </xsl:call-template>
        <xsl:value-of select="@file" />
    </xsl:variable>
        <a href="{$temp}" title="{@name}" ><xsl:value-of select="." /></a>
</xsl:template>

$rootPath وصدر على كل ملف مع ${applicationScope.contextPath} الفكرة من وراء استخدام XML بدلا من مجرد الثابت-ترميز في JSP/Java الملف لم نكن نريد أن تضطر إلى إعادة ترجمة.

مرة أخرى, الحل ليس فكرة جيدة على الإطلاق...ولكن لم تستخدم مرة واحدة!

تحرير:في الواقع ، فإن تعقيد في مسألة نشأت لأننا لم نكن قادرين على استخدام صفحات jsp طوال العرض.لماذا لا مجرد شخص استخدام ${applicationScope.contextPath} لاسترداد سياق المسار ؟ انها عملت بشكل جيد بالنسبة لنا بعد ذلك.

عند إنشاء موقع من الصفر, أنا جنب مع @سوف - تهدف متسقة ويمكن التنبؤ بها بنية عنوان url بحيث يمكنك العصا مع مراجع نسبية.

ولكن يمكن الحصول على أشياء فوضوي حقا إذا كنت تقوم بتحديث الموقع الذي تم بناؤه في الأصل أن تعمل مباشرة تحت جذر الموقع "/" (شائع جدا بسيطة JSP المواقع) الرسمية Java EE التعبئة والتغليف (حيث السياق الجذر سوف يكون هناك بعض الطريق تحت الجذر).

يمكن أن يعني الكثير من التغييرات في التعليمات البرمجية.

إذا كنت ترغب في تجنب أو تأجيل رمز التغييرات, ولكن لا يزال ضمان السياق الصحيح الجذر الرجوع, تقنية لقد اختبرت استخدام بريمج المرشحات.مرشح يمكن أن انخفض إلى القائمة proejct دون تغيير أي شيء (ما عدا web.xml) ، remap أي عنوان المراجع في الخارج HTML إلى المسار الصحيح ، وضمان توجيه بشكل صحيح المشار إليها.

مثال على الموقع للاستخدام رمز متوفرة هنا: EnforceContextRootFilter-1.0-src.zip ملحوظة::الفعلية قواعد رسم الخرائط يتم تنفيذها باستخدام التعابير المنطقية في بريمج الفئة وتوفير جدا العامة جامعا - ولكن قد تحتاج إلى تعديل لظروف خاصة.

راجع للشغل, أنا متشعب قليلا مسألة مختلفة لمعالجة ترحيل البرمجية الموجودة في قاعدة "/" إلى غير الجذر سياق المسار

أنا أميل إلى كتابة الممتلكات كجزء من مكتبة جافا سكريبت الأساسية داخل بلدي.لا أعتقد انها مثالية ولكن أعتقد أنه من الأفضل لقد تمكنت من تحقيقه.

أولا لدي وحدة هذا جزء من بلدي التطبيق الأساسية التي هي دائما المتاحة

(function (APP) {
  var ctx;
  APP.setContext = function (val) {
    // protect rogue JS from setting the context.
    if (ctx) {
      return;
    }
    val = val || val.trim();
    // Don't allow a double slash for a context.
    if (val.charAt(0) === '/' && val.charAt(1) === '/') {
      return;
    }
    // Context must both start and end in /.
    if (val.length === 0 || val === '/') {
      val = '/';
    } else {
      if (val.charAt(0) !== '/') {
        val = '/' + val;
      }
      if (val.slice(-1) !== '/') {
        val += '/';
      }
    }
    ctx = val;
  };
  APP.getContext = function () {
    return ctx || '/';
  };
  APP.getUrl = function (val) {
    if (val && val.length > 0) {
      return APP.getContext() + (val.charAt(0) === '/' ? val.substring(1) : val);
    }
    return APP.getContext();
  };
})(window.APP = window.APP || {});

ثم استخدام apache البلاط مشتركة رأس دائما يحتوي على ما يلي:

<script type="text/javascript">
  APP.setContext('${pageContext.request['contextPath']}');
  // If preferred use JSTL cor, but it must be available and declared.
  //APP.setContext('<c:url value='/'/>');
</script>

الآن بعد أن قمت تهيئة السياق قد استخدم getUrl(path) من أي مكان (js الملفات أو داخل jsp/html) الذي سيعود مطلقة مسار معين سلسلة الإدخال داخل السياق.

علما أن يلي كل ما يعادلها عمدا. getUrl دائما العودة مطلقة مسار مسار نسبي لا حاجة لك إلى معرفة السياق في المقام الأول.

var path = APP.getUrl("/some/path");
var path2 = APP.getUrl("some/path");

هنا هي أفضل طريقة :سياق توجيه تصفية مرشح يجب أن تطبق في قبل المباراة امتداد نقطة وبالتالي استخدام الشرح @PreMatching.

مرشحات تنفيذ هذه الواجهة يجب أن تكون مشروحة مع @مزود يتم اكتشافها من قبل جاكس-RS وقت التشغيل.حاوية طلب تصفية الحالات قد يكون أيضا اكتشفت بد حيوي معين أساليب الموارد.

وأوضح مع نموذج التعليمات البرمجية:

http://writeulearn.com/java-filters/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top