2009-11-12 15 views
11

görüntülemelidir. JSP sayfasını programsal olarak oluşturmam gerekiyor. Anladığım kadarıyla, JSP'nin bir derleyici olması gerekiyordu. Soru bu derleyiciyi JspServlet ve diğerleri olmadan doğru kullanabilir miyim? Tek ihtiyacım olan şey, JSP derleyicisini (örneğin Jasper) nasıl kullanacağınızdır.JSP, programlı bir şekilde

Bazı ek bilgiler durumu netleştirecektir, bence. Standart JspServlet kullanamıyorum. Derleme öncesinde kaynak JSP'yi bir şekilde değiştirmek istiyorum (tam olarak iki JSP'yi birleştirin), bu yüzden JSP derleyicisini doğrudan JSP derleyicisini kullanarak InputStream'den (veya Reader'dan) derlemek için bir yönteme ihtiyacım var.

İki JSP'nin birleşim düzeni gereksinimidir. “Ama neden bu adam SiteMesh'i ya da bunun gibi bir şeyi kullanmıyor?” Diye sorabilirsiniz. JSP sayfalarından biri statik değil. Kullanıcı tarafından sağlanır ve veritabanında saklanır. Bu JSP düzenini dezenfekte edip onaylıyoruz (kullanıcılar etiketlerin sadece alt kümesini kullanabilirler ve hepsi standart değildir, ancak bunlar için özel olarak yaratılmışlardır), önbelleği vb. Ancak şimdi, bu JSP sayfalarını (bellekte saklanan) kullanıcı isteğinin tüm JSP sayfaları için düzenleri olarak kullanması için bir yola ihtiyacımız var.

+1

Benzer bir sorun yaşadım ve bulduğum "en kolay" çözüm, tüm projeyi bu tür görevlerin önemsiz olduğu Velocity (veya başka bir şablon motoru) olarak değiştirmekti. Bu tür değişiklikler yapmak için geliştirme konusunda çok uzaksınız gibi görünüyor, ama sadece ... – serg

cevap

8

Ben programmaticaly JSP sayfanın sunulmasına gerek için şunlardır: Ben jsp öneriyoruz.

İşlevsel gereksinim nedir? Yanlış yöne doğru bir çözüm arıyorsun. Bu, çözümün bu olduğunu düşündüğünüz sorun/gereksinim nedir? Daha iyi öneriler bulabiliriz.

Örneğin sadece çıkışına sahip olmanız gerekiyor? Eğer öyleyse, java.net.URLConnection yeterli olabilir.

Düzenleme: Sorunuzu düzenlendi:

Bir şekilde derleme önce kaynak JSP değiştirmek istiyorum

(kesin olmak için birlikte iki JSP birleştirme), bu yüzden JSP sonucu derlemek için bir yol gerekir Doğrudan JSP derleyicisini kullanarak InputStream (veya Reader) 'dan.

Tamam, bu bir bitlik daha açık. Ama buna ne gerek var? Bu JSP'ler gerçekte neyi temsil ediyor? Nihai sonuç ne için kullanılmalı?

Örneğin sadece bir JSP'yi diğerine eklemek ister misiniz? Örneğin. main.jsp'da head.jsp dahil olmak üzere? Eğer öyleyse, <jsp:include> yeterli olabilir. Ya da daha kötüsü, yeniden kullanmak istediğiniz belirli bir kod ile ham Java kodu içerir mi? Eğer öyleyse, o zaman basit Java sınıfları kullanmalı ve bunun için gerekli ise taglibs.

Düzenleme 2: siz yorum olarak:

Ama şimdi bu kullanıcı tüm JSP sayfaları için düzenleri olarak (mağaza arada bellekte olduğunu vardır), bu JSP sayfalarını kullanmak için bir yol gerekir (ServletContext#getRealPath() buraya kurtarma içine gelebilir)

Sadece web uygulamasının Webcontent içindeki disk dosya sistemi üzerinde JSP dosyaları depolamak isteyebilir ve sınav için kullanarak iki JSP dosyaları içeren kendi ana JSP dosyasında isteği iletmek ple:

<jsp:include page="${page1}" /> 
<jsp:include page="${page2}" /> 

Düzenleme 3: Ben onun çalışma kanıtlamak için bir SSCCE yarattı.

package mypackage; 

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class TestServlet extends HttpServlet { 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException 
    { 
     File root = new File(getServletContext().getRealPath("/")); 

     String main = "<jsp:include page=\"${page1}\" /><jsp:include page=\"${page2}\" />"; 
     write(main, new File(root, "main.jsp")); 

     String page1 = "<p>We are in ${data1}"; 
     write(page1, new File(root, "page1.jsp")); 
     request.setAttribute("page1", "page1.jsp"); 
     request.setAttribute("data1", "first jsp"); 

     String page2 = "<p>We are in ${data2}"; 
     write(page2, new File(root, "page2.jsp")); 
     request.setAttribute("page2", "page2.jsp"); 
     request.setAttribute("data2", "second jsp"); 

     request.getRequestDispatcher("main.jsp").forward(request, response); 
    } 

    private static void write(String content, File file) throws IOException { 
     BufferedWriter writer = null; 
     try { 
      writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); 
      writer.write(content); 
     } finally { 
      if (writer != null) try { writer.close(); } catch (IOException ignore) {} 
     } 
    } 

} 

http://localhost:8080/playground/test (veya kullandığınız ne olursa olsun ev sahibi/contextname) adresinden yürütün ve

We are in first jsp 
We are in second jsp 

daha verimli Her kaynak önbelleğe olacağını yapmak için bkz ve File#exists() faydalanmak edeceğiz Belli bir sayfanın diskte kayıtlı olup olmadığını kontrol edin.

+0

Tamam, şartlara dalalım. İki JSP'nin birleştirme düzeni gereksinimidir. “Ama neden bu adam SiteMesh'i ya da bunun gibi bir şeyi kullanmıyor?” Diye sorabilirsiniz. JSP sayfalarından biri statik değildir. Kullanıcı tarafından sağlanır ve veritabanında saklanır. Bu JSP düzenini dezenfekte edip onaylıyoruz (kullanıcılar etiketlerin sadece alt kümesini kullanabilirler ve hepsi standart değildir, ancak bunlar için özel olarak yaratılmışlardır), önbelleği vb. Ama şimdi, bu JSP sayfalarını kullanmanın bir yolu olmalı (ki bu da bu arada hafızadaydı) kullanıcı isteğinin tüm JSP sayfaları için düzenleri. –

+0

Tamam, işe yarayacak. Ama JSP'imin biraz daha temiz görünmesini istiyorum. ... ve sayfa etiketinin bulunduğu sayfalar gibi. Sayfa etiketi tek başına derleme zamanında düzen ile değiştirir. Bu bir şekilde mümkün mü? –

+0

Sadece JSP içeriğinin üst kısmında taglibs ekleyin. Sadece JSP'yi her zamanki gibi kodlayın. Yapmanız gereken tek şey, onu webapp'un web sitesinde saklamak. Son eklediğim SSCCE'ye bakın. – BalusC

1

Belki Tomcat's JspC ant task'u kullanabilir misiniz?

+0

Tam olarak değil. JSP'yi sunucu tarafında kendi başıma derlemem gerekiyor. Yani karınca görevi aradığım şey değil. Ama bu görevin kaynak kodunu göreceğim. Belki yardımcı olur. Teşekkür ederim. –

1

JSTL, JSP dosyalarında kullanılan etiketlerden oluşan bir kitaplıktır. Yani bu bağlamda gerçekten önemli değil.

Bir JSP derleyici JSP dosyalarını Java Servletlerine dönüştürdüğünden, doğrudan çalıştırdığınızdan (bir derleyici aslında hiçbir şey çalışmaz!) Veya bir JSP dosyası için oluşturduğunuzdan şüpheliyim.

Gerçekten aradığınız soruyu anlamak gerçekten zor.

Düzenleme: iş

+0

Evet, JSTL için bu bağlamda uygunsuz olduğundan bahset, katılıyorum. Ve haklısınız, JSP sayfaları derlendikten sonra servlet olur. İhtiyacım olan şey, JSP sayfalarını servletlere kendi başıma derlemenin bir yoludur.Görevimi biraz daha derinden anlatabilirim. İki JSP dosyasını bir şekilde (kaynaklardan) birleştirmem ve ardından sonucu derlemem gerekiyor. –

+0

JSP dosyalarından birini diğerine dahil etmek yeterli değil mi? Bakınız jsp: include ve <%@include%> –

+0

Ne yazık ki, hayır. JSP birleşimi için kurallar önemsizdir. Bu, kendi başına bir problemdir, ama ... –

1

JSP zaten uygulama sunucusu tarafından önceden derlenmişse, oluşturulan .class dosyasını arayabilirsiniz. Tomcat'ta bu $ CONTEXT_ROOT/org/apache/jsp/directory altında olmalıdır. Bu sınıfı bir şekilde yönetebilir ve çıktılarınızı üretebilirsiniz.

DÜZENLEME: JSP kaynağını değiştirmeyle ilgili düzenlemenizi kaçırdınız.

org.apache.jasper.compiler.AntCompiler dosyasına (Tomcat'daki jasper.jar dosyasında) bakın. GetChield ile adlandırılan korumalı bir yöntem vardır. Bu, sizin için ne yapmamızı ister?

1

Bunu yapmak için nedeniniz var? Eğer işlemek için birleştirme 2 jsp dosyası gerekiyorsa, kullanarak Veya başka fikirlere mi ihtiyacınız var? İsteğiniz hakkında örnek verebilir misiniz?

4

Bunun aradığınız ama DWR framework akım isteği artı bir URL'ye sahte yanıt nesnesi iletir ve sonra belleğe tampon içeriğini okur WebContext.forwardToString adlı bir yöntem içerir buysa tamamen emin değilim. Sen jsp rednering sonuçlarını almak ve bunları bellekte saklamak için kullanabiliriz

StringWriter sout = new StringWriter(); 
StringBuffer buffer = sout.getBuffer(); 

HttpServletResponse realResponse = getHttpServletResponse(); 
HttpServletResponse fakeResponse = new SwallowingHttpServletResponse(realResponse, sout, realResponse.getCharacterEncoding()); 

HttpServletRequest realRequest = getHttpServletRequest(); 
realRequest.setAttribute(WebContext.ATTRIBUTE_DWR, Boolean.TRUE); 

getServletContext().getRequestDispatcher(url).forward(realRequest, fakeResponse); 

return buffer.toString(); 

: İşte bir kod örneği. SwallowingHttpServletResponse'nin nasıl çalıştığını görmek için kaynağı yukarıdaki bağlantıdan indirebilirsiniz.