I use the <p:media> to display static PDF content.
<p:media value="/resource/test.pdf"
width="100%" height="300px" player="pdf">
</p:media>
How can I change it to display dynamic content?
Like as in <p:graphicImage>, the value attribute can point to a bean property returning StreamedContent. This only requires a special getter method for the reasons which is explained in detail in the following answer on using <p:graphicImage> with a dynamic resource from a database: Display dynamic image from database with p:graphicImage and StreamedContent.
In your particular example, it would look like this:
<p:media value="#{mediaManager.stream}" width="100%" height="300px" player="pdf">
<f:param name="id" value="#{bean.mediaId}" />
</p:media>
With
#ManagedBean
#ApplicationScoped
public class MediaManager {
#EJB
private MediaService service;
public StreamedContent getStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
} else {
// So, browser is requesting the media. Return a real StreamedContent with the media bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Media media = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(media.getBytes()));
}
}
}
Related
I'm developing a Spring boot application using Thymeleaf as the view technology. I have a html page dashboard.html inside src/main/resources/templates folder, which is being called from inside a controller.
#PostMapping("/users/register")
public String registerUser(#Validated #ModelAttribute User user, Model model) {
User registeredUser = usersDAO.registerUser(user);
if (registeredUser == null) {
return "500error";
}
model.addAttribute("name", user.getName());
model.addAttribute("username", user.getUsername());
model.addAttribute("emailId", user.getEmailId());
return "dashboard";
}
I have some more static html files inside static folder. I want to call dashboard.html from a static html file like using anchor tag <a/>. How can this be done?
I cannot directly link to this file when my app is running locally. For example: localhost:8080/templates/dashboard.html will not work.
You should create a controller for your thymeleaf html template. For example:
#Controller
#RequestMapping("/templates")
public class DashboardController {
#GetMapping("/dashboard")
public ModelAndView dashboard() {
DashboardModel dashboardModel = new DashboardModel();
return new ModelAndView("dashboard", "dashboard", dashboardModel);
}
}
Then you can link to http://localhost:8080/templates/dashboard and get your dashboard.html page.
Of course you can change the #RequestMapping("/templates") and #GetMapping("/dashboard") to control the url as you like.
I am doing a small project with images using jsp/servlets.In that I generate some image dynamically(actually I'll decrypt two image shares as one).That decrypted image must be displayed directly to browser without saving it as file in filesystem.
Crypting c=new Crypting();
BufferedImage imgKey;
BufferedImage imgEnc;
imgKey = ImageIO.read(new File("E:/Netbeans Projects/banking/web/Key.png"));
imgEnc=ImageIO.read(new File("E:/Netbeans Projects/banking/build/web/upload/E.png"));
BufferedImage imgDec=Crypting.decryptImage(imgKey,imgEnc);
When I store it in filesystem and display it using <img> it does not show the image.When reloaded it shows the image.So it is problem with the backend work of IDE.
Any help pls...
Make a servlet to generate images.
Use html img tag with attribute src, as a path to your genarated resource.
Example in spring boot (QR Codes).
Servlet
public class QRCodeServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String url = req.getParameter("url");
String format = req.getParameter("format");
QRCodeFormat formatParam = StringUtils.isNotEmpty(format) && format.equalsIgnoreCase("PDF") ?
QRCodeFormat.PDF : QRCodeFormat.JPG;
if(formatParam.equals(QRCodeFormat.PDF))
resp.setContentType("application/pdf");
else
resp.setContentType("image/jpeg");
if(StringUtils.isNotBlank(url)) {
ByteArrayOutputStream stream = QRCodeService.getQRCodeFromUrl(url, formatParam);
stream.writeTo(resp.getOutputStream());
}
}
}
Configuration:
#Configuration
public class WebMvcConfig {
#Bean
public ServletRegistrationBean qrCodeServletRegistrationBean(){
ServletRegistrationBean qrCodeBean =
new ServletRegistrationBean(new QRCodeServlet(), "/qrcode");
qrCodeBean.setLoadOnStartup(1);
return qrCodeBean;
}
}
Conroller:
String qrcodeServletPrefix = "http://localhost:8082/qrcode?url="
String encodedUrl = URLEncoder.encode("http://exmaple.com?param1=value1¶m2=value2", "UTF-8");
modelAndView.addObject("qrcodepage", qrcodeServletPrefix + encodedUrl);
modelAndView.setViewName("view");
view.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<img src="<c:url value='${qrcodepage}'/>" />
used jersey mvc and jsp, all requests to html or js files did through #Template or Viewable.
example;
#GET
#Path(JS_URL + "{type}")
#Template(name = "grid")
#Produces("application/javascript")
public Response buildJSGrid(#DefaultValue("") #PathParam("type") String type) {
Grid grid = new Grid(type);
....
return Response.ok(grid).build();
}
where grid is grid.jsp file with pure javascript inside
<%# page contentType="application/javascript;charset=UTF-8" language="java" %>
.....
also possible other variant with html and js, example;
#GET
#Path(FORM_URL + "{type}")
#Template(name = "form")
#Produces(MediaType.TEXT_HTML)
public Response buildAccountForm(#DefaultValue("") #PathParam("type") String type) {
Form form = new Form(type);
....
return Response.ok(form).build();
}
where form is form.jsp with html and js inside <script>..</script>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
...
i need to minify result js and html/js before send to client, i try to use https://code.google.com/archive/p/htmlcompressor/ lib, but there need to pass String to htmlCompressor.compress(input);
tried use WriterInterceptor
public class MinifyJsInterceptor implements WriterInterceptor {
#Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
final OutputStream outputStream = context.getOutputStream();
// here need to convert outputStream to InputStream and after to String ?
// result string to htmlCompressor.compress(resultString);
// after that convert result minify string back to resultOutputStream and set to context ?
context.setOutputStream(new GZIPOutputStream(resultOutputStream));
is it correct way ? and i can`t converts that outputstream to string
thanks
--update
answer to questions;
html + js mean that in some jsp are html markup and js code
<div id="form" style="width: 500px; display: none">
<div class="w2ui-page page-0">
<div class="w2ui-field">
</div>....
<script type="text/javascript">
var uiElement = (function () {
var config = {
onOpen: function (event) {
event.onComplete = function () {
$('#formContainer').w2render('form');
}
...
}());
</script>
on client that file requested by
$('#tempContainer').load('that file name - also dynamic', function (data, status, xhr) {
uiElement.init();
w2ui[layout].content(layout_main, w2ui[uiElement.name]);
});
And do you really return js-files in you resource methods?
some js and html + js files are dynamic build, example;
grid.jsp contains inside
<%# page contentType="application/javascript;charset=UTF-8" language="java" %>
var uiElement = (function () {
var config = {
grid: {
name: ${it.name},
listUrl:'${it.entityListUrl}',
formUrl:'${it.entityFormUrl}',
columns: ${it.columns},
records: ${it.records},
}}
there are ${it..} values from el expression and setting in resource method
#GET
#Path(JS_URL + "{type}")
#Template(name = "grid")
#Produces("application/javascript")
public Response buildJSGrid(#DefaultValue("") #PathParam("type") String type) {
Grid grid = new Grid(type);
....
return Response.ok(grid).build();
}}
and from client that js 'file' called by
$.getScript('dynamic js file name' - it is dynamic too).done(function (script, status, xhr) {
//console.log(xhr.responseText);
uiElement.init();
w2ui[layout].content(layout_main, w2ui[uiElement.name]);
});
also some html blocks build dynamic
{
<c:if test="${it.recid != 0}">
<div class="w2ui-field">
<label>active:</label>
<div>
<input name="active" type="checkbox"/>
</div>
</div>
</c:if>
}
-- update description,
grid builder;
one resource and one template for build any grid,
#GET
#Path(GRID + "{type}")
#Template(name = W2UI_VIEW_PREFIX + "grid/grid")
#Produces(MEDIA_TYPE_APPLICATION_JAVASCRIPT)
public Response buildGrid(#DefaultValue("") #PathParam("type") String type) {
for (W2UI ui : W2UI.values()) {
if (type.equals(ui.getName())) {
W2UIElement grid = ui.getUI();
return Response.ok(grid).build();
}
}
return Response.noContent().build();
}
also possible different templates(jsp files) through Viewable(template, model)
somewhere in menu builder for menu.jsp template
List<MenuItem> items..
MenuItem item1 = new MenuItem(W2UI.TASK_GRID, W2UIService.GRID);
items.add(item1);
where
W2UIService.GRID is string url for client js request and for server method resource #Path() anno.
and
public enum W2UI {
TASK_GRID("task_grid", "tasks", Type.SCRIPT){
#Override
public W2UIElement getUI() {
return new TaskGrid(getName());
}
},
.....
}
TaskGrid is filled model for grid.jsp template with js code, so easy to add any type of grid with different sets of data and buttons.
type of component(Type.SCRIPT) processing on the client by $.getScript(), Type.HTML by $('#tempContainer').load()
---update factory and providers;
#Provider
#Priority(200)
#HtmlMinify
public class HtmlMinifyInterceptor implements WriterInterceptor {
#Inject private HtmlCompressor compressor;
...
public class HtmlMinifierFactory implements Factory<HtmlCompressor> {
private HtmlCompressor compressor;
#Override
public HtmlCompressor provide() {
if (null == compressor) compressor = new HtmlCompressor();
ClosureJavaScriptCompressor jsCompressor = new ClosureJavaScriptCompressor();
jsCompressor.setCompilationLevel(CompilationLevel.SIMPLE_OPTIMIZATIONS);
..
#ApplicationPath("/")
public class MainRsConfig extends ResourceConfig {
public MainRsConfig() {
..
register(new AbstractBinder() {
#Override
protected void configure() {
bindFactory(HtmlMinifierFactory.class).to(HtmlCompressor.class).in(Singleton.class);
}
});
..
You can use a custom implementation of a ByteArrayOutputStream as a wrapper to the OutputStream of the WriterInterceptorContext:
import com.googlecode.htmlcompressor.compressor.Compressor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class HtmlMinifyOutputStream extends ByteArrayOutputStream {
private OutputStream origOut;
private Compressor compressor;
public HtmlMinifyOutputStream(OutputStream origOut, Compressor compressor) {
this.origOut = origOut;
this.compressor = compressor;
}
public void close() throws IOException {
super.close();
String compressedBody = compressor.compress(new String(this.buf));
this.origOut.write(compressedBody.getBytes());
this.origOut.close();
}
}
The HtmlMinifyOutputStream can be used in the WriterInterceptor implementation. The HtmlCompressor instance is injected:
import com.googlecode.htmlcompressor.compressor.Compressor;
import javax.inject.Inject;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import java.io.*;
#Provider
#HtmlMinify
public class MinifyHtmlInterceptor implements WriterInterceptor {
#Inject
private Compressor compressor;
#Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new HtmlMinifyOutputStream(outputStream, compressor));
context.proceed();
}
}
#HtmlMinify is a NameBinding annotation, used to activate the MinifyHtmlInterceptor on specific resource methods. (see https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9988):
import javax.ws.rs.NameBinding;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#NameBinding
#Retention(value = RetentionPolicy.RUNTIME)
public #interface HtmlMinify {}
The HtmlCompressor can be created only once per application and used concurrently, because:
HtmlCompressor and XmlCompressor classes are considered thread safe* and can be used in multi-thread environment (https://code.google.com/archive/p/htmlcompressor/)
Here is a HK2 factory (see: Implementing Custom Injection Provider) which creates the compressor instance and enables inline css and javascript compression:
import com.googlecode.htmlcompressor.compressor.Compressor;
import com.googlecode.htmlcompressor.compressor.HtmlCompressor;
import org.glassfish.hk2.api.Factory;
public class HtmlCompressorFactory implements Factory<Compressor> {
private HtmlCompressor compressor;
#Override
public Compressor provide() {
if(compressor == null) {
compressor = new HtmlCompressor();
}
compressor.setCompressJavaScript(true);
compressor.setCompressCss(true);
return compressor;
}
#Override
public void dispose(Compressor compressor) {}
}
The factory is registered with an AbstractBinder:
final ResourceConfig rc = new ResourceConfig().packages("com.example");
rc.register(new AbstractBinder() {
#Override
protected void configure() {
bindFactory(HtmlCompressorFactory.class).to(Compressor.class).in(Singleton.class);
}
});
If inline javascript or inline css compression is enabled:
HTML compressor with default settings doesn't require any dependencies. Inline CSS compression requires YUI compressor library.Inline JavaScript compression requires either YUI compressor library (by default) or Google Closure Compiler library. (https://code.google.com/archive/p/htmlcompressor/)
I use maven, so I added this dependency to my pom.xml:
<dependency>
<groupId>com.yahoo.platform.yui</groupId>
<artifactId>yuicompressor</artifactId>
<version>2.4.8</version>
</dependency>
If you want to use the Google Closure Compiler use this dependency:
<dependency>
<groupId>com.google.javascript</groupId>
<artifactId>closure-compiler</artifactId>
<version>r2388</version>
</dependency>
and activate it:
compressor.setJavaScriptCompressor(new ClosureJavaScriptCompressor());
compressor.setCompressJavaScript(true);
compressor.setCssCompressor(new YuiCssCompressor());
compressor.setCompressCss(true);
return compressor;
If you want to compress pure JavaScript or CSS files, you cannot use the htmlcompressor. This library supports only HTML files with inline CSS/JS. But you could implement a MinifyJsInterceptor or MinifyCssInterceptor analog to the MinifyHtmlInterceptor, which uses the YUI-Compressor and/or Google Closure libraries directly.
For gzip compression you should implement another interceptor. So it is possible to configure the minification and compression separately. If you activate multiple interceptors, use javax.annotation.Priority to controll the order of execution. (see: https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9927)
This question already has answers here:
How to call servlet class from HTML form
(2 answers)
Closed 7 years ago.
Im trying to create a Servlet application. When I hit the submit button I want to clear the forms and add the information to a unordered list and store the data. The issue is that I do not know how to evaluate when the button is pushed.
package org.gephi.demos;
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
// Extend HttpServlet class
#WebServlet(name = "HelloWorld", urlPatterns = {"/test"}, loadOnStartup=1)
public class HelloWorld extends HttpServlet {
private String message;
private File f;
private GephiBuilder gb;
//private Main m;
public void init() throws ServletException
{
gb = new GephiBuilder();
System.out.println("Initialized");
// Do required initialization
message = "Hello World for sure";
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Set response content type
response.setContentType("text/html");
//m = new Main(gb);
// Actual logic goes here.
PrintWriter out = response.getWriter();
out.println(HTMLUserInput("do you want a Nodes(n) or auto(a)", "directory", "d"));
String directory = request.getParameter("d");
// do some processing here...
// build HTML code
if(request.getParameter("button")!=null)
{
System.out.println("Hello");
//response.getParameter("d").valu;
String htmlRespone = "<html>";
htmlRespone += "<h2>Your directory is: " + directory + "<br/>";
htmlRespone += "</html>";
// return response
out.println(htmlRespone);
}
//out.println(addJSCode());
}
public String HTMLUserInput(String question, String id, String name){
String htmlOutput = "<form action=\"HelloWorld\"><label>"+question+"</label>"
+"<input name = \""+name+"\" id=\""+id+"\" type=\"text\"/>"
+"<input id=\"button\" type=\"button\">Submit</form>";
return htmlOutput;
}
public void destroy()
{
// do nothing.
}
}
If I press the button nothing changes, I imagine because this code is only evaluated on startup, how do I get it evaluated anytime I press my submit button.
1.You have to use URL for your servlet(wich was specified in servlet mapping) in action attribute . For example: <form action='/test'>
2.There is several way how to submit the form to the server. You can use <input type="submit">Submit</input> inside form tag .
Or if you want to use tag button you have to set id attribute for the form (<form id='myform' .../>) and connect button with the form specifying this id in form attribute:
<button type="submit" form="myform">Submit</button>
And button tag does not have to be located within form tag.
3.After that you can get the content of your form using request.getParameter("input name") and handle these data.
Use <input type="submit" /> instead of <button>
Your urlPatterns = {"/xxxxx"}, should match form action="xxxxx"
i am trying to put a video inside my jsp page, dynamically, like:
<video id="myVideo" width="420" height="345" controls="controls">
<source src="#{detailsBean.ref.videoLink}" type="video/ogg" /> </video>
But I get this error : org.apache.jasper.JasperException: /details.jsp(64,29) #{..} is not allowed in template text
What should i use instead?
package beans;
import dto.Referinta;
public class DetailsBean
{
Referinta ref = new Referinta( );
public Referinta getRef ( )
{
return ref;
}
public void setRef ( Referinta ref )
{
this.ref = ref;
}
}
I dont think that the problem is in the bean, it's about the tag, can't find one to use with dynamic src. This will work if in src i put the direct link to the video.