I have customs tags as follows. repeat and heading tag have doAfterBody method implemented.Both of them extends BodyTagSupport class
<csajsp:repeat reps="5">
<LI>
<csajsp:heading bgColor="BLACK">
White on Black Heading
</csajsp:heading>
</LI>
</csajsp:repeat>
Repeat tag Class
public void setReps(String repeats) {
System.out.println("TESTING"+repeats);
//sets the reps variable.
}
public int doAfterBody() {
System.out.println("Inside repeate tag"+reps);
if (reps-- >= 1) {
BodyContent body = getBodyContent();
try {
JspWriter out = body.getEnclosingWriter();
System.out.println("BODY"+body.getString());
out.println(body.getString());
body.clearBody(); // Clear for next evaluation
} catch(IOException ioe) {
System.out.println("Error in RepeatTag: " + ioe);
}
return(EVAL_BODY_TAG);
} else {
return(SKIP_BODY);
}
}
Class of Heading tag
public int doAfterBody()
{
System.out.println("inside heading tag");
BodyContent body = getBodyContent();
System.out.println(body.getString());
try {
JspWriter out = body.getEnclosingWriter();
out.print("NEW TEXT");
} catch(IOException ioe) {
System.out.println("Error in FilterTag: " + ioe);
}
// SKIP_BODY means I'm done. If I wanted to evaluate
// and handle the body again, I'd return EVAL_BODY_TAG.
return(SKIP_BODY);
}
public int doEndTag() {
try {
JspWriter out = pageContext.getOut();
out.print("NEW TEXT 2");
} catch(IOException ioe) {
System.out.println("Error in HeadingTag: " + ioe);
}
return(EVAL_PAGE); // Continue with rest of JSP page
}
Custom tag tld file is
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>csajsp</shortname>
<uri></uri>
<tag>
<name>heading</name>
<tagclass>com.test.tags.HeadingTag</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>bgColor</name>
<required>true</required> <!-- bgColor is required -->
</attribute>
</tag>
<tag>
<name>repeat</name>
<tagclass>com.test.tags.RepeatTag</tagclass>
<info>Repeats body the specified number of times.</info>
<bodycontent>JSP</bodycontent>
<attribute>
<name>reps</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
The order in which SOP are printed is
Setter method of csajsp:repeat is called.
White on Black Heading is printed. ie doAfterBody of csajsp:heading tag is called.
I don't know why it is not calling doAfterBody of csajsp:repeat tag.
Please help me to understand this.
What class do your tags extend?
The default behaviour of TagSupport is to return SKIP_BODY, which would skip processing of the tag body.
The default behaviour of BodyTagSupport is to return EVAL_BODY_BUFFERED, which would process the tag body.
If you are implementing BodyTag yourself, then you need to make sure you override doStartTag correctly to indicate that the JSP body should be evaluated.
Related
I want to modify the HTML body tag when I open a Wicket-Bootstrap Modal. What I'm trying to achieve is <body class="modal-open"> instead of <body>
Using Wicket 8 M8 , I have this code:
owsImportDialog = new MyModalBootstrapDialog("owsImportDialog"
, new CompoundPropertyModel<>(new BopOwsTO())) {
#Override
void importOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel) {
appendCloseDialogJavaScript(target);
BopOwsTO owsTo = owsModel.getObject();
try {
importOwsCapabilities(owsTo);
owsViewDialog.header(Model.of("OWS anzeigen"))
.setModel(Model.of(owsTo.getServiceId()));
owsViewDialog.appendShowDialogJavaScript(target);
}
catch (OwsCapsImportException e) {
String localizedMessage = e.getLocalizedMessage();
importAlert.setModelObject(localizedMessage);
importAlert.appendShowDialogJavaScript(target);
error(localizedMessage);
}
finally {
target.appendJavaScript("document.getElementsByTagName('body')[0]" +
".setAttribute('class', 'modal-open');");
// target.appendJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.prependJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.appendJavaScript("alert('Hallo');");
// owsViewDialog is a child of owsView WebMarkupContainer
target.add(owsView, feedback);
}
}
#Override
void saveOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel)
{ }
#Override
void cancel(AjaxRequestTarget target)
{ }
};
If the line target.appendJavaScript("alert('Hallo');"); is active I actually see the alert window.
I also tried this code in the page class:
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
PackageResourceReference resourceReference = new PackageResourceReference(
getClass(), "../css/BuiOwsPage.css");
CssReferenceHeaderItem cssRef = CssReferenceHeaderItem.forReference(resourceReference);
response.render(cssRef);
response.render(OnLoadHeaderItem
.forScript("document.body.setAttribute('class', 'modal-open');"));
}
But none of my attempts was succesful.
Update
The answer of #martin-g didn't solve the issue.
I'm quite sure that the problem is caused by the sequence of these statements:
{
appendCloseDialogJavaScript(target);
...
try {
owsViewDialog.appendShowDialogJavaScript(target);
....
}
catch { ... }
finally {
target.add(owsView, feedback);
}
}
When this modal is closed because of appendCloseDialogJavaScript() ,
the class modal-open is erased from the class attribute of the <body> .
Then owsViewDialog opens, but modal-open isn't inserted in class, no matter if I append the snippet jQuery(document.body).addClass('modal-open') or not. The missing modal-open means that the page can't be scrolled.
Since Wicket and Bootstrap are used then jQuery is also available. I would recommend you to use jQuery(document.body).addClass('modal-open').
There must be a reason why jQuery has both addClass() and attr()!
I having a rss file in following :
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title> سایپا نیوز </title>
<link>http://www.saipanews.com/</link>
<description></description>
<language>fa</language>
<item>
<author></author>
<pretitle></pretitle>
<title>پیام تبریک دکتر جمالی به مناسبت فرارسیدن سالروز ولادت حضرت علی(ع) و روز پدر</title>
<link>http://www.saipanews.com/view-6751.html</link>
<pubdate>2016-04-20 10:58:00</pubdate>
<description>سایپا نیوز: مدیرعامل گروه خودروسازی سایپا همزمان با فرارسیدن سالروز میلاد باسعادت حضرت علی(ع) و روز پدر، طی پیامی به تمامی پدران متعهد و پرتلاش ایران زمین تبریک گفت.</description>
<secid>0</secid>
<typid>8</typid>
<image>http://www.saipanews.com/media/image/jamali/jmali.JPG</image>
</item>
<item>
<author></author>
<pretitle></pretitle>
<title>فرهنگ رانندگی بین خطوط در معابر شهری در حال گسترش است </title>
<link>http://www.saipanews.com/view-6748.html</link>
<pubdate>2016-04-19 11:27:00</pubdate>
<description>سایپا نیوز: به گزارش سایپا نیوز و به نقل از فرارو، از آنجایی که فرهنگ رانندگی مجموعه ای از رفتارهای درست رانندگی و آداب زندگی اجتماعی بهنگام تردد در شهرها و جاده ها است، رانندگی در بین خطوط معابر شهری یکی از نمادهای فرهنگ رانندگی در کشورهای درحال توسعه و توسعه یافته می باشد.</description>
<secid>0</secid>
<typid>8</typid>
<image>http://www.saipanews.com/media/image/farhang%20ranandegi/252887_331.jpg</image>
</item>
</channel>
</rss>
I want to get image's urls.
I use Rome library but not found any solution.
how to get image's url in item with Rome library ?
I for that get image tag , build new rss parser on the following:
public class NewRssParser extends RSS094Parser implements WireFeedParser {
public NewRssParser() {
this("rss_2.0");
}
protected NewRssParser(String type) {
super(type);
}
protected String getRSSVersion() {
return "2.0";
}
protected boolean isHourFormat24(Element rssRoot) {
return false;
}
protected Description parseItemDescription(Element rssRoot, Element eDesc) {
Description desc = super.parseItemDescription(rssRoot, eDesc);
desc.setType("text/html"); // change as per
// https://rome.dev.java.net/issues/show_bug.cgi?id=26
return desc;
}
public boolean isMyType(Document document) {
boolean ok;
Element rssRoot = document.getRootElement();
ok = rssRoot.getName().equals("rss");
if (ok) {
ok = false;
Attribute version = rssRoot.getAttribute("version");
if (version != null) {
// At this point, as far ROME is concerned RSS 2.0, 2.00 and
// 2.0.X are all the same, so let's use startsWith for leniency.
ok = version.getValue().startsWith(getRSSVersion());
}
}
return ok;
}
#Override
public Item parseItem(Element arg0, Element arg1) {
Item item = super.parseItem(arg0, arg1);
Element imageElement = arg1.getChild("image", getRSSNamespace());
if (imageElement != null) {
String imageUrl = imageElement.getText();
Element urlElement = imageElement.getChild("url");
imageUrl = urlElement != null ? urlElement.getText() : imageUrl;
Enclosure enc = new Enclosure();
enc.setType("image");
enc.setUrl(imageUrl);
item.getEnclosures().add(enc);
}
return item;
}
}
in the class override parseItem method and add code for get image element and add image's url to Enclosures.
then add following line to rome.properties file :
WireFeedParser.classes=[packge name].NewRssParser
Example :
WireFeedParser.classes=ir.armansoft.newscommunity.newsgathering.parser.impl.NewRssParser
Rome wont provide the <image> tag because it does not belong to the namespace it is in. So the feed isn't valid:
line 18, column 3: Undefined item element: image (29 occurrences) [help]
<image>http://www.saipanews.com/media/image/%D8%AA%D9%88%D9%84%D9%8A%D8%A ...
If the image tag would be in a different namespace, like this:
<image:image>http://www.saipanews.com/media/image/%D8%AA%D9%88%D9%84%D9%8A%D8%AF/2.jpg</image:image>
You could get foreing markup in this way:
for(SyndEntry entry : feed.getEntries()) {
for (Element element : entry.getForeignMarkup()) {
System.out.println("element: " + element.toString());
}
}
And the result would be
element: [Element: <image:image [Namespace: http://purl.org/rss/1.0/modules/image/]/>]
Unless the feed is fixed, It seems that there isn't a way to get the image url with Rome library at the moment.
The Answer is so simple.
First get the syndContent using the Roam API.
Find the code for the reading images and all content from RSS
<%# page import="com.rometools.rome.feed.synd.SyndFeed"%>
<%# page import="com.rometools.rome.feed.synd.SyndEntry"%>
<%# page import="com.rometools.rome.feed.synd.SyndContent"%>
<%# page import="com.rometools.modules.mediarss.MediaEntryModule"%>
<%# page import="com.rometools.rome.feed.module.Module"%>
<%# page import="com.rometools.modules.mediarss.types.Thumbnail"%>
<%# page import="java.util.Iterator"%>
<%# page import="java.util.List"%>
<html>
<head>
<title>website</title>
<link href="/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Home</h1>
<%
HttpSession session1=request.getSession(false);
SyndFeed syndFeed11= (SyndFeed) session1.getAttribute("syndFeed");
%>
<h2><%=syndFeed11.getTitle()%></h2>
<ul>
<%
Iterator it = syndFeed11.getEntries().iterator();
while (it.hasNext())
{
SyndEntry entry = (SyndEntry) it.next();
%>
<li><%=entry.getTitle()%> <%
List<SyndContent> syndContents=entry.getContents();
System.out.println(syndContents.size());
for(SyndContent syndContent:syndContents)
{
System.out.println(syndContent.getMode());
System.out.println("This is content"+syndContent.getValue());
%>
//This is The STRING WHICH CONTAINS the link to the image apply regex expression to get SAMPLE_LINK out of "<img src"LINK">"
<%=syndContent.getValue() %>>
<%
}
//SyndContent syndContent=syndContents.get(0);
for (Module module : entry.getModules()) {
if (module instanceof MediaEntryModule) {
MediaEntryModule media = (MediaEntryModule)module;
for (Thumbnail thumb : media.getMetadata().getThumbnail()) {
%><img src="<%=thumb.getUrl() %>" />
<%
}
}
}
%></li>
<% } %>
</ul>
</body>
</html>
Bellow is the Servlet Class:-
package website.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.FeedException;
import com.rometools.rome.io.SyndFeedInput;
import com.rometools.rome.io.XmlReader;
public class HomeServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
private Logger logger = Logger.getLogger(this.getClass());
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String rssUrl=(String)req.getAttribute("rss");
logger.debug("Retrieving yahoo news feed");
URL url = new URL("https://www.reddit.com/.rss");
SyndFeedInput syndFeedInput = new SyndFeedInput();
HttpSession session=req.getSession();
SyndFeed syndFeed = null;
XmlReader xmlReader = new XmlReader(url);
try {
syndFeed = syndFeedInput.build(xmlReader);
System.out.println("Donr");
} catch (IllegalArgumentException e) {
logger.error("", e);
} catch (FeedException e) {
logger.error("", e);
}
logger.debug("Forwarding to home.jsp");
req.setAttribute("syndFeed11", syndFeed);
PrintWriter out = resp.getWriter();
out.println("<h1>");
out.println();
session.setAttribute("syndFeed", syndFeed);
out.println("</h1>");
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getRequestDispatcher("/WEB-INF/jsp/home.jsp");
dispatcher.forward(req,resp);
}
}
I solved this problem by parsing the feed with Rome and then parsing it again to get the raw jdom Document. Then I can get the item elements from the feed and look for images. Bit hacky but it easier than extending the RSS parsers and so on.
byte[] data = ... bytes for the feed ...
SyndFeedInput input = new SyndFeedInput()
input.allowDoctypes = true
SyndFeed sf = input.build(new XmlReader(new ByteArrayInputStream(data)))
Document doc = new MyWireFeedInput().getDocument(new XmlReader(new ByteArrayInputStream(data)))
Element channel = doc.rootElement.getChild("channel")
List<Element> items = channel ? channel.getChildren("item") : null
List<SyndEntry> entries = sf.entries
for (int i = 0; i < entries.size(); i++) {
SyndEntry entry = entries[i]
Element item = items ? items[i] : null
if (item) {
Element image = item.getChild("image")
... add it to enclosures or whatever ...
}
}
Here is the class that gets the jdom Document:
/**
* This is a hack to get at the protected {#link WireFeedInput#createSAXBuilder()} method so we can get the
* raw jdom document for the feed to extract elements (e.g. 'image') not parsed by the built in feed parsers.
*/
public class MyWireFeedInput extends WireFeedInput {
Document getDocument(Reader reader) {
final SAXBuilder saxBuilder = createSAXBuilder();
try {
if (xmlHealerOn) reader = new XmlFixerReader(reader)
return saxBuilder.build(reader);
} catch (final JDOMParseException ex) {
throw new ParsingFeedException("Invalid XML: " + ex.getMessage(), ex);
} catch (final IllegalArgumentException ex) {
throw ex;
} catch (final Exception ex) {
throw new ParsingFeedException("Invalid XML", ex);
}
}
}
I just tried to add a custom taglib to my project, such that the testtaglib.tld file contains:
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>name</shortname>
<tag>
<name>test</name>
<tagclass>taglib.TestTaglib</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>testCode</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
<taglib>
And then I added taglib class TestTaglib.java
public class TestTaglib extends TagSupport {
private String testCode;
public int doStartTag() throws JspException {
try {
JspWriter out = pageContext.getOut();
//doing some conversion with testCode
out.print(testCode);
return EVAL_PAGE;
} catch(IOException ioe) {
throw new JspException("Error: " + ioe.getMessage());
}
}
}
And then in .jsp file
<name:test testCode="${testCode}"/>
Okay the issue is:TestTaglib.java is recognizing values of testCode as ${testCode} and not the original value. Any suggestion?
Hi all inbuilt tag already handles the expression language. Just change your code as mentioned below and it will work fine.
public class TestTaglib extends TagSupport {
private String testCode;
public int doStartTag() throws JspException {
try {
JspWriter out = pageContext.getOut();
//doing some conversion with testCode
String value = (String) ExpressionUtil.evalNotNull("test", "testCode", testCode, String.class, this, pageContext);
out.print(value);
return EVAL_PAGE;
} catch(IOException ioe) {
throw new JspException("Error: " + ioe.getMessage());
}
}
}
ExpressionUtil is class provided under org.apache.taglibs.standard.tag.el.core package.
Here is short desc of evalNotNull method args
1) tagName : your tag name is test
2) tagAttribute: to eval in your case it is testCode
3) expression : which is el expression ${testCode}
4) Value: Class of expression value whether it is Boolean,String or any Object
5) tagClass: Reference of tag handler class so you can pass this
6) pageContext: which is coming from TagSupport
I'm using Flying Saucer to convert XHTML to a PDF document. I've gotten the code to work with just basic HTML and in-line CSS, however, now I'm attempting to add an image as a sort of header to the PDF. What I'm wondering is if there is any way whatsoever to add the image by reading in an image file as a Java Image object, then adding that somehow to the PDF (or to the XHTML -- like it gets a virtual "url" representing the Image object that I can use to render the PDF). Has anyone ever done anything like this?
Thanks in advance for any help you can provide!
I had to do that last week so hopefully I will be able to answer you right away.
Flying Saucer
The easiest way is to add the image you want as markup in your HTML template before rendering with Flying Saucer. Within Flying Saucer you will have to implement a ReplacedElementFactory so that you can replace any markup before rendering with the image data.
/**
* Replaced element in order to replace elements like
* <tt><div class="media" data-src="image.png" /></tt> with the real
* media content.
*/
public class MediaReplacedElementFactory implements ReplacedElementFactory {
private final ReplacedElementFactory superFactory;
public MediaReplacedElementFactory(ReplacedElementFactory superFactory) {
this.superFactory = superFactory;
}
#Override
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) {
Element element = blockBox.getElement();
if (element == null) {
return null;
}
String nodeName = element.getNodeName();
String className = element.getAttribute("class");
// Replace any <div class="media" data-src="image.png" /> with the
// binary data of `image.png` into the PDF.
if ("div".equals(nodeName) && "media".equals(className)) {
if (!element.hasAttribute("data-src")) {
throw new RuntimeException("An element with class `media` is missing a `data-src` attribute indicating the media file.");
}
InputStream input = null;
try {
input = new FileInputStream("/base/folder/" + element.getAttribute("data-src"));
final byte[] bytes = IOUtils.toByteArray(input);
final Image image = Image.getInstance(bytes);
final FSImage fsImage = new ITextFSImage(image);
if (fsImage != null) {
if ((cssWidth != -1) || (cssHeight != -1)) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
} catch (Exception e) {
throw new RuntimeException("There was a problem trying to read a template embedded graphic.", e);
} finally {
IOUtils.closeQuietly(input);
}
}
return this.superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight);
}
#Override
public void reset() {
this.superFactory.reset();
}
#Override
public void remove(Element e) {
this.superFactory.remove(e);
}
#Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
this.superFactory.setFormSubmissionListener(listener);
}
}
You will notice that I have hardcoded here /base/folder which is the folder where the HTML file is located as it will be the root url for Flying Saucer for resolving medias. You may change it to the correct location, coming from anywhere you want (Properties for example).
HTML
Within your HTML markup you indicate somewhere a <div class="media" data-src="somefile.png" /> like so:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My document</title>
<style type="text/css">
#logo { /* something if needed */ }
</style>
</head>
<body>
<!-- Header -->
<div id="logo" class="media" data-src="media/logo.png" style="width: 177px; height: 60px" />
...
</body>
</html>
Rendering
And finally you just need to indicate your ReplacedElementFactory to Flying-Saucer when rendering:
String content = loadHtml();
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(new MediaReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory()));
renderer.setDocumentFromString(content.toString());
renderer.layout();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos);
// baos.toByteArray();
I have been using Freemarker to generate the HTML from a template and then feeding the result to FlyingSaucer with great success. This is a pretty neat library.
what worked for me is putting it as a embedded image. So converting image to base64 first and then embed it:
byte[] image = ...
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString("<html>\n" +
" <body>\n" +
" <h1>Image</h1>\n" +
" <div><img src=\"data:image/png;base64," + Base64.getEncoder().encodeToString(image) + "\"></img></div>\n" +
" </body>\n" +
"</html>");
renderer.layout();
renderer.createPDF(response.getOutputStream());
Thanks Alex for detailed solution. I'm using this solution and found there is another line to be added to make it work.
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) {
Element element = blockBox.getElement();
....
....
final Image image = Image.getInstance(bytes);
final int factor = ((ITextUserAgent)userAgentCallback).getSharedContext().getDotsPerPixel(); //Need to add this line
image.scaleAbsolute(image.getPlainWidth() * factor, image.getPlainHeight() * factor) //Need to add this line
final FSImage fsImage = new ITextFSImage(image);
....
....
We need to read the DPP from SharedContext and scale the image to display render the image on PDF.
Another suggestion:
We can directly extend ITextReplacedElement instead of implementing ReplacedElementFactory. In that case we can set the ReplacedElementFactory in the SharedContext as follows:
renderer.getSharedContext().setReplacedElementFactory(new MediaReplacedElementFactory(renderer.getOutputDevice());
Say I have my custom taglib:
<%# taglib uri="http://foo.bar/mytaglib" prefix="mytaglib"%>
<%# taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<mytaglib:doSomething>
Test
</mytaglib:doSomething>
Inside the taglib class I need to process a template and tell the JSP to re-evaluate its output, so for example if I have this:
public class MyTaglib extends SimpleTagSupport {
#Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("<c:out value=\"My enclosed tag\"/>");
getJspBody().invoke(null);
}
}
The output I have is:
<c:out value="My enclosed tag"/>
Test
When I actually need to output this:
My enclosed tag
Test
Is this feasible? How?
Thanks.
Tiago, I do not know how to solve your exact problem but you can interpret the JSP code from a file. Just create a RequestDispatcher and include the JSP:
public int doStartTag() throws JspException {
ServletRequest request = pageContext.getRequest();
ServletResponse response = pageContext.getResponse();
RequestDispatcher disp = request.getRequestDispatcher("/test.jsp");
try {
disp.include(request, response);
} catch (ServletException e) {
throw new JspException(e);
} catch (IOException e) {
throw new JspException(e);
}
return super.doStartTag();
}
I tested this code in a Liferay portlet, but I believe it should work in other contexts anyway. If it don't, I would like to know :)
HTH
what you really need to have is this:
<mytaglib:doSomething>
<c:out value="My enclosed tag"/>
Test
</mytaglib:doSomething>
and change your doTag to something like this
#Override public void doTag() throws JspException, IOException {
try {
BodyContent bc = getBodyContent();
String body = bc.getString();
// do something to the body here.
JspWriter out = bc.getEnclosingWriter();
if(body != null) {
out.print(buff.toString());
}
} catch(IOException ioe) {
throw new JspException("Error: "+ioe.getMessage());
}
}
make sure the jsp body content is set to jsp in the tld:
<bodycontent>JSP</bodycontent>
Why do you write a JSTL tag inside your doTag method?
The println is directly going into the compiled JSP (read: servlet) When this gets rendered in the browser it will be printed as it is since teh browser doesn't understand JSTL tags.
public class MyTaglib extends SimpleTagSupport {
#Override public void doTag() throws JspException, IOException {
getJspContext().getOut().println("My enclosed tag");
getJspBody().invoke(null);
}
}
You can optionally add HTML tags to the string.