From the Servlet I am generating JPEG image and writing in the outputstream of that servlet.By jsp i am calling this Servlet URL and displaying the image as similar to user profile with photo.
Here the problem is,When first time login it will generate the image dynamically and display but next time if I login with out closing the browser first it will display the privies picture and then it will display the current picture.
JSP:
<div class="sortable">
<div class="box span5" style="margin-left: 50px;">
<div class="box-header well">
<h2><i class="icon-th"></i>Employee Attendance</h2>
<div class="box-icon">
<i class="icon-chevron-up"></i>
</div>
</div>
<div class="box-content" style="height:230px;" >
<img border="0" src="admissionenquirylist.do?method=image" alt="Pulpit rock" width="370" height="240"/>
</div>
</div>
</div>
Servlet:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.treamis.admission.process;
import com.google.gson.Gson;
import com.treamis.entity.Academicyearmaster;
import com.treamis.entity.AdmissionenquiryStudentdetails;
import com.treamis.entity.EmployeeEntity;
import com.treamis.hr.employee.PaginationClass;
import com.treamis.hr.employee.SetPaginationRecords;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.actions.LookupDispatchAction;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.ServletOutputStream;
/**
*
* #author ranjeeth.g
*/
public class AdmissionEnquiry extends LookupDispatchAction {
/* forward name="success" path="" */
private final static String SUCCESS = "success";
/**
* Provides the mapping from resource key to method name.
*
* #return Resource key / method name map.
*/
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("button.admissionEnqiryList", "admissionEnqiryList");
map.put("button.image", "image");
map.put("button.delete", "delete");
return map;
}
/**
* Action called on Add button click
*/
public void admissionEnqiryList(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
// TODO: implement add method
try {
String stdutendserch = request.getParameter("admissionenquirysearch");
System.out.println("stdutendserch = " + stdutendserch);
Admissionservices as = new Admissionservices();
List<Enquirylistbean> stdserc = as.getStudentEnquirySerch(stdutendserch);
if (stdserc != null) {
response.setContentType("application/json");
String json = new Gson().toJson(stdserc);
System.out.println("json = " + json);
response.getWriter().print(json);
} else {
response.setContentType("application/json");
String json = new Gson().toJson(null);
response.getWriter().print(json);
}
} catch (Exception e) {
e.printStackTrace();
}
// return mapping.findForward(SUCCESS);
// return null;
}
/**
* Action called on Edit button click
*/
public void image(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
try {
System.out.println("Inside the image responce action");
response.setContentType("image/jpeg");
Academicyearmaster academicyearmaster = (Academicyearmaster) request.getSession().getAttribute("academicyear");
// String ss = getServlet().getServletContext().getRealPath("\\");
// String filePath = ss + "img\\paichart.png";
ServletOutputStream out = response.getOutputStream();
// System.out.println("out = " + out);
// String filePath2 = ss + "img\\paichart1.png";
// ExecutorService executor = Executors.newFixedThreadPool(2);
com.treamis.hr.employee.Sendded sendded = new com.treamis.hr.employee.Sendded(out, academicyearmaster);
sendded.image();
// executor.execute(sendded);
} catch (Exception e) {
e.printStackTrace();
}
// TODO: implement edit method
// return mapping.findForward(SUCCESS);
}
/**
* Action called on Delete button click
*/
public ActionForward delete(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws java.lang.Exception {
// TODO:implement delete method
return mapping.findForward(SUCCESS);
}
/* And your JSP would have the following format for submit buttons:
<html:form action="/test">
<html:submit property="method">
<bean:message key="button.add"/>
</html:submit>
<html:submit property="method">
<bean:message key="button.edit"/>
</html:submit>
<html:submit property="method">
<bean:message key="button.delete"/>
</html:submit>
</html:form>
*/
}
Java code to generate image:
try{
ChartUtilities.writeChartAsJPEG(out, chart, 600, 400, info);
// System.out.println("file2 = " + file1);
} catch (Exception e) {
e.printStackTrace();
return "success";
} finally {
out.close();
}
The answer lies in the Life cycle of Servlet. Even though multiple request comes to a servlet only one instance of the Servlet class will be created.
Check if you have any resources that is global and fix it.
Or post full servlet class for better response.
Hope it helps!
I think if you use differents files names to each file save in disk you will not have this problem again.
Related
I have to generate pdf of HTML page. I have written a method for this but it generates an error. Please guide me where I'm wrong. Thank You!
public void htmlToPdf(
String htmlPath,
File pdfFile
) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(
document,
new FileOutputStream(pdfFile)
);
document.open();
XMLWorkerHelper.getInstance().parseXHtml(
writer,
document,
new FileInputStream(htmlPath),
Charset.forName("UTF-8")
);
document.close();
}
Error :
Cannot resolve method 'parseXHtml(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document, java.io.FileInputStream, java.nio.charset.Charset)'
So you want to generate PDFs from HTML with Java? (check EDIT 2020 at the bottom)
Here is the procedure I am using with flying-saucer.
Format your HTML with CSS 2.1
Write the process to generate a PDF
Create the PDF generator interface
Use a custom object to wrap images with attributes for further formatting
Implements your interface with your PDF parameters and images
1. Format your HTML with CSS 2.1
Example can be a JSP with ELs, any other template (you will be able to get the
generated HTML with parameters with an internal POST request), or just static
HTML.
You cannot use proportionnal values like em, rem, vh, vw or complex
CSS like animations.
You can use <style> </style> tag or inline style= attribute
Here is an example of a JSP in my webapp.
<!DOCTYPE html>
<%# page session="false"
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<META CHARSET="UTF-8" />
<title>My PDF</title>
<style>
/* you can add reset css too */
/* stylesheet */
body { font-family: sans-serif; }
.someCSSClass {}
.anotherCSSClass {}
</style>
</head>
<body>
<div class="someCSSClass">
<p class="anotherCSSClass" style="line-height:16px;">
${ param.aParameter }
</p>
2. Write the process to generate a PDF with an interface
Why using an interface? Because in the case you need to generate additional
PDFs from different models you will not have to write the same logic to
generate each PDFs.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImage;
import com.itextpdf.text.pdf.PdfIndirectObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import main.java.bean.ImagePDF;
import main.java.interface.PDFInterface;
import main.java.bean.Constants;
/**
* PDFGenerator
* Class to generate PDF (can implement Servlet).
*/
public class PDFGenerator {
private static final String TMP_DIR = System.getProperty("java.io.tmpdir");
/*
* May not be a GET, can be simple method call for local application or
* whatever you need
*/
#Override
protected void goGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
PDFInterface pdfImplementation = null;
/*
* instance your PDF Model implementation according to this
* parameter (for example)
*/
int pdfModel = Integer.parseInt(
request.getParameter("requestedPDFModel")
);
switch (pdfModel) {
case Constants.PDF_MODEL_1:
pdfImplementation = new PDFImplementationOne();
/*
* You could get the image reference from GET request too,
* or from database or from constants
*/
pdfImplementation.addImage(
"image1.png",
120,
50,
"image_name1",
request
);
break;
case Constants.PDF_MODEL_2:
pdfImplementation = new PDFImplementationTwo();
pdfImplementation.addImage(
"image2.png",
350,
70,
"image_name2",
request
);
break;
default :
System.out.println("Cannot find an implementation for the requested PDF.");
return null;
}
String html = null;
/*
Get the HTML from an URL : if your implementation returns null
then you can for example decide to get the HTML from a file in your implementation
*/
if (pdfImplementation.getUrl(request) != null) {
// Send POST request to generate the HTML from a template (JSP, JSF, Thymeleaf, ...)
URLConnection connection = new URL(
pdfImplementation.getUrl(request)
+pdfImplementation.getEncodedQueryString()
).openConnection();
connection.setDoOutput(true); // POST : remove this to do a GET
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8"
);
try (OutputStream output = connection.getOutputStream()) {
output.write(
pdfImplementation
.getEncodedQueryString()
.getBytes(StandardCharsets.UTF_8)
);
}
// Open an input stream on the response
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream())
);
StringBuilder sb = new StringBuilder();
// A line in our generated HTML
String inputLine;
// Read all HTML lines and concatenate
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
html = sb.toString();
in.close();
}
// Get the HTML from a File
else {
html = String.join(
"",
Files.readAllLines(pdfImplementation.getHTMLFile().toPath())
);
}
// Create a temp file to make the PDF
File tempPDFFile = new File(
TMP_DIR + pdfImplementation.getGeneratedPDFFileName()
);
if (!tempPDFFile.exists()) { tempPDFFile.createNewFile(); }
FileOutputStream fos = new FileOutputStream(tempPDFFile);
// Output the HTML to the temp PDF file
new ITextRenderer() {{
setDocumentFromString(html);
layout();
createPDF(fos);
}};
fos.close();
// Create your final PDF file
File pdf = new File(pdfImplementation.getPDFFilename());
// Add images if needed
addImageToPDF(pdfImplementation, tempPDFFile, pdf);
// Write in response if you need servlet implementation
writePDFContentToResponse(pdf, response);
}
/**
* writePDFContentToResponse
* #param pdf : the final PDF file
* #param response : a HTTPServletResponse to write PDF file bytes
* #throws IOException
*/
void writePDFContentToResponse(
File pdf,
HttpServletResponse response
) throws IOException {
InputStream fis = new FileInputStream(pdf);
String mimeType = getServlet().getServletContext()
.getMimeType(pdf.getAbsolutePath());
response.setContentType(
mimeType != null ? mimeType : "application/octet-stream"
);
response.setContentLength((int) pdf.length());
response.setHeader(
"Content-Disposition",
"attachment; filename="+pdf.getName()+".pdf"
);
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read = 0;
while((read = fis.read(bufferData)) != -1) {
os.write(bufferData, 0, read);
}
os.flush();
os.close();
fis.close();
response.flushBuffer();
Files.delete(pdf.toPath());
}
/**
* addImageToPDF
*
* #param pdfImplementation : the pdfImplementation to get the array of
* custom image objects ImagePDF.
* #param tempPDFFile : the temp PDF file with already HTML content
* converted.
* #param pdf : the final PDF file which will have images stamped.
* #throws DocumentException
* #throws IOException
*/
void addImageToPDF(
PDFInterface pdfImplementation,
File tempPDFFile,
File pdf
) throws DocumentException, IOException {
PdfReader reader = new PdfReader(new FileInputStream(tempPDFFile));
PdfStamper stamper = new PdfStamper(
reader,
new FileOutputStream(pdf)
);
for (ImagePDF img: pdfImplementation.getImages()) {
Image image = img.getImage();
image.scalePercent(img.getScale());
PdfImage stream = new PdfImage(image, "", null);
stream.put(
new PdfName("ITXT_SpecialId"),
new PdfName("123456789")
);
PdfIndirectObject ref = stamper.getWriter().addToBody(stream);
image.setDirectReference(ref.getIndirectReference());
image.setAbsolutePosition(
img.getWidthPosition(),
img.getHeightPosition()
);
PdfContentByte over = stamper.getOverContent(1);
over.addImage(image);
}
stamper.close();
reader.close();
}
}
3. Create the PDF generator interface
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.itextpdf.text.BadElementException;
/**
* PDFInterface
* Interface to define the behavior a PDF model has to implement.
*/
public interface PDFInterface {
/**
* getUrl
* #param request the HTTPServletRequest to fetch parameters for the PDF
* #return the URL target to make a HTTP POST request to get the generated
* HTML (for example if you are making a HTTP POST on a JSP to generate
* HTML dynamically.
*/
String getUrl(HttpServletRequest request);
/**
* getHTMLFile
* #return return the HTML file from the local storage to be read to get
* the HTML.
*/
File getHTMLFile();
/**
* setParametres
* #param object : an object or a list of objects to be encoded to the
* query String to generate the PDF.
*/
void setParametres(Candidat candidat);
String getEncodedQueryString();
/**
* getImages
* #return a custom ImagePDF object with needed attributes to add an image
* after the PDF has been generated has the HTML cannot be read to get
* image during the generation of the PDF.
*/
List<ImagePDF> getImages();
/**
* addImage
* #param url : the URL to get the image
* #param x : the X position
* #param y : the Y position
* #param name : the name of the image
* #param request : the HTTPServletRequest to generate the relative link
* to fetch the image.
* #param scale : the scale of the image
* #throws BadElementException
* #throws IOException
*/
void addImage(
String url,
float x,
float y,
String name,
HttpServletRequest request,
float scale
) throws BadElementException, IOException;
/**
* getPDFFilename
* #return : the name of the PDF file to be generated
*/
String getPDFFilename();
}
4. The ImagePDF object (in case you need to add image to your PDF)
import java.io.IOException;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Image;
/**
* ImagePDF
* Class for a custom ImagePDF object to fit needs to stamp an image on a
* generated PDF (URI to get the image, scale, positions x y ...).
*/
public class ImagePDF implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Image image;
private float widthPosition;
private float heightPosition;
private String name;
private Float scale;
/**
* ImagePDF
* #param urlImage : the URL to fetch the image
* #param heightPosition : the y position on the PDF canvas
* #param widthPosition : the x position on the PDF canvas
* #param name : the name of the image
* #param scale : the scale of the image on the PDF canvas
* #throws BadElementException
* #throws IOException
*/
public ImagePDF(
String urlImage,
float widthPosition,
float heightPosition,
String name,
Float scale
) throws BadElementException, IOException {
this.image = Image.getInstance(urlImage);
this.heightPosition = heightPosition;
this.widthPosition = widthPosition;
this.name = name;
this.scale = scale;
}
// Getters and setters ...
5. Implements your interface for your PDF parameters
(used in example above)
/**
* PDFImplementationOne
* The PDFImplementation to generate a specific PDF.
*/
public class PDFImplementationOne implements PDFInterface {
private static final String PARAM_1 = "param1";
private static final String PARAM_2 = "param2";
private Map<String, String> parameters;
private List<ImagePDF> images;
/**
* PDFImplementationOne
* You can pass service to add information retreival from DB or objects to
* pass to parameters in the constructor if needed.
*/
public PDFImplementationOne (CustomObject aParameter) {
this.parameters = new HashMap<>();
this.images = new ArrayList<>();
// in case you need parameters, passed in constructor
setParametres(aParameter);
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#getUrl()
*/
#Override
public String getUrl(HttpServletRequest request) {
/*
* This is an example in case your generate your HTML from JSP with
* parameters, if it is from static file then return null
*/
StringBuilder sb = new StringBuilder("http://");
sb.append(request.getServerName());
sb.append((request.getServerName().startsWith("127.0.0")?":8080":""));
sb.append("/MyApp/urlToJSP");
return sb.toString();
}
/*
* (non-Javadoc)
* #see main.java.interface.PDFInterface#addImage(
* java.lang.String,
* float,
* float,
* java.lang.String,
* javax.servlet.http.HttpServletRequest,
* float scale
* )
*/
#Override
public void addImage(
String fileName,
float x,
float y,
String name,
HttpServletRequest request
) {
/*
* Here I get the image from a ressource server but you can read the
* image from local storage as well
*/
StringBuilder url = new StringBuilder("http://");
url.append(request.getServerName());
url.append(request.getServerName().startsWith("127.0.0")?":8080":"");
url.append("/MyApp/img/");
url.append(fileName);
try {
ImagePDF image = new ImagePDF(url.toString(), x, y, name, scale);
images.add(image);
}
catch (BadElementException | IOException e) {
System.out.println(Cannot set image for PDF "+url.toString());
}
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#getImages()
*/
#Override
public List<ImagePDF> getImages() {
return this.images;
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#setParameters(
* CustomObject customObject
* )
*/
#Override
public void setParametres(CustomObject customObject) {
parametres.put(PARAM_1, customObject.getAttribute().toString());
// may have other parameters ...
}
/* (non-Javadoc)
* #see model.bean.ResultatsEcritsPDF#getEncodedQueryString()
*/
#Override
public String getEncodedQueryString() {
/*
* Create the queryString to do further HTTP POST or GET to fetch the
* generated HTML with parameters
*/
StringBuilder queryStringBuilder = new StringBuilder("?");
parameters.entrySet().stream().forEach(e -> {
queryStringBuilder.append(e.getKey());
queryStringBuilder.append("=");
try {
queryStringBuilder.append(
URLEncoder.encode(
e.getValue() == null
? ""
: e.getValue(),
StandardCharsets.UTF_8.name()
)
);
}
catch (UnsupportedEncodingException e1) {
queryStringBuilder.append("");
}
queryStringBuilder.append("&");
});
// Remove the last &
return queryStringBuilder.toString().substring(
0,
queryStringBuilder.toString().length()-1
);
}
/* (non-Javadoc)
* #see model.bean.PDFInterface#getHTMLFile()
*/
#Override
public File getHTMLFile() {
return new File("/path/to/myHTMLFile.html");
}
/* (non-Javadoc)
* #see model.bean.PDFInterface#getPDFFilename()
*/
#Override
public String getPDFFilename() {
return "myPDF.pdf";
}
}
Tell me if it needs some clarification.
EDIT 2020
Things are much simpler now with the improvement of libraries and calling HTTP server itself to generate the dynamic HTML content is not enough simpler and requires additional network configuration in some case.
Here is the new process :
Make a HTML template with CSS2.1 (with <style> tag or inline style=") and include template expressions (EL-style or whatever)
Fetch HTML template as String
Replace template expressions "${ }" in HTML
Replace images in HTML like <img src="image.png" /> by encoded base64 images
Make the PDF file
Write it to response or whatever
Here is the project structure I am using (for example) :
main
|--java
|--bean
|--PdfConverter.java
|--resources
|--pdf
|--template.html
|--img
|--image.png
Dependencies :
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.20</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-core</artifactId>
<version>9.1.20</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-openpdf</artifactId>
<version>9.1.20</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.9</version>
</dependency>
HTML template (with images) :
<html>
<head>
<style>
body {
font-family:sans-serif;
font-size:14px;
margin: 0 auto;
padding: 0;
}
h1 {
text-align:center;
font-size:21px;
text-transform:capitalize;
}
</style>
</head>
<body>
<h1>some title</h1>
<p>Some paragraph : ${ foo }</p>
<!-- you can style images with CSS! -->
<img src="image.png" style="width:50px;height:50px" />
</body>
</html>
PdfConverter :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Map;
import java.util.Scanner;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.apache.poi.util.IOUtils;
import org.springframework.http.MediaType;
import org.xhtmlrenderer.pdf.ITextRenderer;
/**
* PdfConverter
* Extends this to implement additional to make the map to replace template
* expressions.
* #author user
* #since 28 juil. 2020
*/
public class PdfConverter {
/**
* Temp directory.
*/
private static final String TMP_DIR =
System.getProperty("java.io.tmpdir") + "/";
/**
* Directory to HTML templates (dedicated to PDF generation).
*/
private static final String PDF_DIR =
"pdf/";
/**
* Directory to the image folders (dedicated to PDF generation).
*/
private static final String PDF_IMG_DIR =
"pdf/img/";
/**
* Prefixes for templates expressions.
*/
private static final String PREFIX_TEMPLATE = "${ ";
/**
* Suffixes for template expressions.
*/
private static final String SUFFIX_TEMPLATE = " }";
/**
* Generated PDF file.
*/
private File generatedPDF;
/**
* PDF file name.
*/
private String pdfName;
/**
* PdfConverter
* #param m map key, value to replace, to replace expressions in HTML
* template.
* #param s ServletContext to get resources from context path.
* #param fileName desired name of the generated PDF.
* #param template name of the HTML template to make the PDF.
* #throws IOExceptio
*/
public PdfConverter(
Map<String, String> m,
ServletContext s,
String fileName,
String template
) throws IOException {
// Set PDF filename
setPdfName(fileName);
// Fetch HTML template
#SuppressWarnings("resource")
String html = new Scanner(
s.getResourceAsStream(PDF_DIR+ template),
StandardCharsets.UTF_8.toString()
).useDelimiter("\\A").next();
/*
* Replace template expressions "${ }" in HTML
*/
StringSubstitutor sub = new StringSubstitutor(
m,
PREFIX_TEMPLATE,
SUFFIX_TEMPLATE
);
String resolvedString = sub.replace(html);
/*
* Replace images like <img src="image.png" /> by
* <img src=\"data:image/png;base64," + base64Image
*/
String[] imgs = StringUtils.substringsBetween(
resolvedString,
"<img src=\"", "\""
);
for (String s1 : imgs) {
String mime = Files.probeContentType(Paths.get(PDF_IMG_DIR + s1));
resolvedString = resolvedString.replace(
s1,
"data:" + mime + ";base64,"
+ Base64.getEncoder().encodeToString(
IOUtils.toByteArray(
s.getResourceAsStream(PDF_IMG_DIR + s1)
)
)
);
}
// Make the PDF file
FileOutputStream fos = new FileOutputStream(TMP_DIR+getPdfName());
ITextRenderer it = new ITextRenderer();
it.setDocumentFromString(resolvedString);
it.layout();
it.createPDF(fos);
fos.close();
// Set the PDF generated file to this PdfConverter instance
setGeneratedPDF(new File(TMP_DIR+getPdfName()));
}
/**
* getGeneratedPDF
*
* #return the generatedPDF
*/
public File getGeneratedPDF() {
return generatedPDF;
}
/**
* setGeneratedPDF
*
* #param generatedPDF the generatedPDF to set
*/
public void setGeneratedPDF(File generatedPDF) {
this.generatedPDF = generatedPDF;
}
/**
* getPdfName
*
* #return the pdfName
*/
public String getPdfName() {
return pdfName;
}
/**
* setPdfName
*
* #param pdfName the pdfName to set
*/
public void setPdfName(String pdfName) {
this.pdfName = pdfName;
}
/**
* writePdfToResponse
* Write the PDF file into the response and delete it from temp directory
* afterwards.
* #param response
* #throws IOException
*/
public void writePdfToResponse(
HttpServletResponse response
) throws IOException {
try (
FileInputStream fis =
new FileInputStream(getGeneratedPDF())
) {
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
response.setHeader(
"Content-Disposition",
"inline; filename=" + getPdfName()
);
response.addHeader(
"Content-Length",
Long.toString(getGeneratedPDF().length())
);
ServletOutputStream servletOutputStream =
response.getOutputStream();
int read = 0;
byte[] bytes = new byte[1024];
while ((read = fis.read(bytes)) != -1) {
servletOutputStream.write(bytes, 0, read);
}
response.flushBuffer();
}
catch (IOException ioe) {
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.getWriter().print("Cannot render PDF file.");
response.flushBuffer();
}
finally {
// Delete generated PDF after writing it to the response
getGeneratedPDF().delete();
}
}
}
And how to use it in servlet (Spring MVC example) :
/**
* downloadPDF
*
* #param response
* #param foo
* #throws IOException
*/
#PostMapping("/downloadPDF")
public void downloadPDF(
HttpServletRequest request,
HttpServletResponse response,
String foo
) throws IOException {
Map<String, String> m = new HashMap<>();
m.put("foo", "my_foo_value");
PdfConverter pdfConverter = new PdfConverter(
m,
request.getServletContext(),
"my_pdf",
"template"
);
pdfConverter.writePdfToResponse(response);
}
Am trying to retrieve records from a database.Connection to database is verified on eclipse, but no information is updated on the jsp table. Am using a servlet class for dispatching, a java class for database replication (model) and jsp (view) that displays the table.
Here is MyUtils.DbAcess class containing the "forRecipient" method`
package myPackage.Utils;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import java.sql.Connection;
import myPackage.beans.MatchTable;
import myPackage.beans.PhedUser;
import myPackage.beans.UserAccount;
public class DbAcess {
.
.
.
public static MatchTable forRecipient(Connection conn, String
recipient) throws SQLException {
String query = "SELECT payer, payerPhone, payerEmail FROM
match_table WHERE recipientAccName=?;";
PreparedStatement ps = conn.prepareStatement(query);
ps.setString(1, recipient);
ResultSet rs = ps.executeQuery();
List <MatchTable> list = new ArrayList<MatchTable>();
while(rs.next()) {
String payer = rs.getString("payer");
String payerPhone = rs.getString("payerPhone");
String payerEmail = rs.getString("payerEmail");
MatchTable payerDetails = new MatchTable();
payerDetails.setPayer(payer);
payerDetails.setPayerPhone(payerPhone);
payerDetails.setPayerEmail(payerEmail);
list.add(payerDetails);
}
return list;
}
This is my database model which is the MatchTable.java
package myPackage.beans;
import java.io.Serializable;
public class MatchTable implements Serializable {
private String payer, payerPhone, payerEmail, recipientAccName,
recipientBankName, recipientAccNumber, recipientPhone;
public MatchTable() {
// TODO Auto-generated constructor stub
}
public MatchTable(String payer, String payerPhone, String payerEmail) {
this.payer = payer;
this.payerPhone = payerPhone;
this.payerEmail = payerEmail;
}
public MatchTable(String recipientAccName, String recipientBankName, String recipientAccNumber, String recipientPhone) {
this.recipientAccName = recipientAccName;
this.recipientBankName = recipientBankName;
this.recipientAccNumber = recipientAccNumber;
this.recipientPhone = recipientPhone;
}
public String getPayer() {
return payer;
}
public void setPayer (String payer) {
this.payer = payer;
}
public String getPayerPhone() {
return payerPhone;
}
public void setPayerPhone(String payerPhone) {
this.payerPhone = payerPhone;
}
public String getPayerEmail() {
return payerEmail;
}
public void setPayerEmail(String payerEmail) {
this.payerEmail = payerEmail;
}
public String getRecipientAccName() {
return recipientAccName;
}
public void setRecipientAccName(String recipientAccName) {
this.recipientAccName = recipientAccName;
}
public String getRecipientBankName() {
return recipientBankName;
}
public void setRecipientBankName(String recipientBankName) {
this.recipientBankName = recipientBankName;
}
public String getRecipientAccNumber() {
return recipientAccNumber;
}
public void setRecipientAccNumber(String recipientAccNumber) {
this.recipientAccNumber = recipientAccNumber;
}
public String getRecipientPhone() {
return recipientPhone;
}
public void setRecipientPhone(String recipientPhone) {
this.recipientPhone = recipientPhone;
}
}
Then I call the "DbAcess.forRecipient" method in my Servlet class and request dispatch to view jsp file "ghTransactions" below;
package myPackage.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import myPackage.Utils.DbAcess;
import myPackage.Utils.SessionAccess;
import myPackage.beans.MatchTable;
import myPackage.beans.UserAccount;
/**
* Servlet implementation class GHTransaction
*/
#WebServlet(urlPatterns={"/ghTransactions"})
public class GHTransactionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public GHTransactionServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
HttpSession session = request.getSession();
Connection conn = SessionAccess.getStoredConnection(request);
//Get stored match details
//MatchTable payerDetails = SessionAccess.getStoredMatchTable(session);
String errorString = null;
String payer = null;
String payerPhone = null;
String payerEmail = null;
MatchTable Payer = new MatchTable(payer, payerPhone, payerEmail);
//Get loggedInUser Details to retrieve user account name for query to match table database
UserAccount loggedInUser = SessionAccess.getStoredLoggedInUser(session);
String recipientAccName = loggedInUser.getAccountName();
try{
DbAcess.forRecipient(conn, recipientAccName);
} catch (SQLException e) {
e.printStackTrace();
errorString = e.getMessage();
}
request.setAttribute("user", loggedInUser.getUserName());
request.setAttribute("payer", Payer);
RequestDispatcher dispatcher = request.getServletContext().getRequestDispatcher("/WEB-INF/views/ghTransactionView.jsp");
dispatcher.forward(request, response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
My stackTrace snapshot shows successful connection to the database
Sat Apr 29 18:54:11 WAT 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
However the view is not populated with the records even when there are matching details.
Below is the ghTransactionView.jsp file
<section id="about">
<div class="container">
<div class="row">
<center>
<h3>Payer Details</h3>
<table style="width:100%; padding:6px;" border="1" cellpadding="3" cellspacing="3">
<tr>
<th> Name</th>
<th> Phone</th>
<th> Email</th>
</tr>
<c:forEach items="${payer }" var="payerDetails">
<tr>
<td>${payerDetails.payer }</td>
<td>${payerDetails.payerPhone }</td>
<td>${payerDetails.payerEmail }</td>
</tr>
</table>
</center>
</div>
</div>
</section>
I need assistance as to where I have gone wrong and why the records are not populated.
Thank you.
You did not collect and pass the queried list to the JSP i.e., the data returned from forRecipient has not been used.
So you need to add the below code in your GHTransactionServlet doGet() method:
//Collect the returned list using a ref. variable
List<MatchTable> matchTableList =DbAcess.forRecipient(conn, recipientAccName);
//Now set the data to request scope so that JSP can access it
request.setAttribute("payer", matchTableList);
Also, the important point is that the request scope matchTableList object has been set with key as payer which is the same as the items attribute for the tag c:forEach inside JSP.
I am developing a web application using Java. From my index page I need to upload a file with some other fields such as some texts and numbers using input tags.
this is my jsp file.
<select name="category">
<option value="">-Select-</option>
<option value="Mobile Phones">Mobile Phones</option>
<option value="Automobile">Automobile</option>
<option value="Computers">Computers</option>
</select><br/><br/>
<label>Title: </label><input type="text" name="Title"/><br/><br/>
<label>Photo: </label><input type="file" name="photo"/><br/><br/>
<label>Description: </label><input type="text" name="description"/><br/><br/>
<label>Price: </label><input type="text" name="price"/><br/><br/>
<input type="submit" value="Post">
I found some articles which use Apache commons, but in all of that, I can get only the image. All the other values get set to null. The article I followed is this.
I need to know how to get other values as well. (In this case category, title, photo etc.)
How can I do that?
Thank you!
EDIT:
This is my servlet.
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.im.dao.PostAdDao;
import com.im.dao.PostAdDaoImpl;
import com.im.entities.Advertiesment;
#WebServlet("/postAd")
#MultipartConfig
public class PostAdServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String UPLOAD_DIRECTORY = "C:/uploadss";
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Advertiesment ad = new Advertiesment();
PostAdDao pad = new PostAdDaoImpl();
PrintWriter out = response.getWriter();
String name = null;
if(ServletFileUpload.isMultipartContent(request)){
try {
List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for(FileItem item : multiparts){
if(item.isFormField()){
String cat = request.getParameter("category");
System.out.println("INFO: Category : "+cat);
if( cat != null ){
ad.setCategory(cat);
}
String title = request.getParameter("adTitle");
if( title != null ){
ad.setTitle(title);
System.out.println("INFO: Title : "+title);
}
String des = request.getParameter("description");
if(des != null){
ad.setDescription(des);
System.out.println("INFO: Description : "+des);
}
try{
Double price = Double.parseDouble(request.getParameter("price"));
if(price != null){
ad.setPrice(price);
System.out.println("INFO: Price : "+price);
}
}catch(Exception e){
System.out.println("ERROR: Occured while setting price in servlet");
}
}else{
name = new File(item.getName()).getName();
item.write( new File(UPLOAD_DIRECTORY + File.separator + name));
}
}
//File uploaded successfully
request.setAttribute("message", "Advertiesment Posted Successfully");
System.out.println("INFO: Advertiesment Posted Successfully");
System.out.println("INFO: File name : "+name);
ad.setPhoto(name);
} catch (Exception ex) {
request.setAttribute("message", "File Upload Failed due to " + ex);
System.out.println("\nERROR: Occured while posting the advertiesment! "+ex );
}
}else{
//request.setAttribute("message","Sorry this Servlet only handles file upload request");
}
//request.getRequestDispatcher("/result.jsp").forward(request, response);
String msg = pad.postAd(ad);
}
}
I found some articles which use Apache commons, but in all of that, I
can get only the image
No . you can get other items also from the request .
DiskFileUpload upload = new DiskFileUpload();
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
//get form fields here
}
else {
//process file upload here
}}
Read the documentation here to understand more on this and also a nice thread here values of input text fields in a html multipart form
Update:
String cat = item.getFieldName("category") instead of request.getParameter("category");
Because you are parsing the request object . so you need to get it from FileItem object . similarly for other fields too.
I'm working in a project that I didn't originally start, so there are a lot of artifacts and conventions that I cannot change without considerable effort. Anyway, here's the problem. I need to do multiple file uploads (that are "children" to the entity that is being edited on the "main" parent page) that get cached on the server so that they can be sent somewhere else if/when the user submits. The files uploaded also include metadata that the user enters. The best way I have figured to do this is to render a "dialog" that has an iframe that does the uploading and has the input for the metadata. Then I created an override (using install precedence) of Seam's multipart filter that uses the Apache file upload jar and a custom request wrapper that carries my information into the action call on the server. All goes well unless I throw an exception out of the filter, for example, if the request size is too big. The exception is caught and handled by a pages.xml declaration.
<exception class="org.jboss.seam.web.FileUploadException">
<redirect view-id="#{facesContext.externalContext.requestServletPath}">
<message severity='ERROR'>#{org.jboss.seam.handledException.message}</message>
</redirect>
</exception>
When I normally submit the form in my dialog frame, the conversation in the frame remains (as I want), when the exception is caught, I get a new one (as I don't want). I want the error messages passed by the exception shown in the global messages area of the frame, but I need to remain in the same conversation as before since the "children" that are being added in the dialog are children to the "parent" entity in the main page. Here is the form inside the frame code. I have tried s:button (does not submit the form), tried parameters, and tried hidden inputs with the conversation id.
<h:form id="attachmentModalForm" enctype="multipart/form-data" autocomplete="off" style="background-color: #FFFFFF;">
<ui:include src="layout/messages.xhtml" />
<div id="attachmentModalMain" class="modalMain">
<s:decorate id="attachmentDescriptionDecoration" template="layout/edit.xhtml" styleClass="twoCol">
<ui:define name="label">#{messages['contents.attachmentDialog.label.description']}<s:span styleClass="required">*</s:span></ui:define>
<h:inputText id="attachmentDescription" value="#{attachmentAction.description}" styleClass="textbox" />
</s:decorate>
<s:decorate id="attachmentFileDecoration" template="layout/edit.xhtml" styleClass="twoCol">
<ui:define name="label">#{messages['contents.attachmentDialog.label.file']}<s:span styleClass="required">*</s:span></ui:define>
<input id="attachmentFile" name="attachmentFile" type="file" />
</s:decorate>
</div>
<div id="attachmentModalSubmit" class="modalSubmit">
<h:commandButton id="attachmentSubmitButton" value="#{messages['action.text.submit']}" action="#{attachmentAction.addAttachment()}" onclick="attachmentSubmit();" />
<button id="attachmentCancelButton" type="button" value="#{messages['action.text.cancel']}" onclick="window.parent.hideAttachmentModal();">#{messages['action.text.cancel']}</button>
</div>
<input type="hidden" name="cid" value="#{conversation.id}" />
</h:form>
Here is the filter that overrides Seam's multipart filter.
package XXXXXXXXXXXXX.attachment;
import java.io.File;
import java.io.IOException;
import java.rmi.server.UID;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.annotations.web.Filter;
import org.jboss.seam.web.AbstractFilter;
/**
* This filter is used to override Seam's multipart filter so that we
* can have multiple temporary files on the server cued and ready to
* go to XXXXXXXXX. It uses the Apache Commons FileUpload objects to
* handle the parsing of the request and the temporary files.
*
*/
#Scope(ScopeType.APPLICATION)
#Name("org.jboss.seam.web.multipartFilter")
#Install(precedence = Install.APPLICATION)
#BypassInterceptors
#Filter(within={"org.jboss.seam.web.ajax4jsfFilter", "org.jboss.seam.web.exceptionFilter"})
public class MEDWareMultipartFilter extends AbstractFilter {
// This is unused, we always want temp files since we are caching before upload to XXXXXXXXX.
// Leaving it in to mirror Seam's multipart filter, in case it gets set from the components.xml.
#SuppressWarnings("unused") private boolean createTempFiles = true;
private int maxRequestSize = -1;
private String acceptedFileExtensions = "txt,pdf,doc,docx,xls,xlsx";
public void setCreateTempFiles(boolean createTempFiles) { }
public void setMaxRequestSize(int maxFileSize) {
this.maxRequestSize = maxFileSize;
}
public String getAcceptedFileExtensions() {
return acceptedFileExtensions;
}
public void setAcceptedFileExtensions(String acceptedFileExtensions) {
this.acceptedFileExtensions = acceptedFileExtensions;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!(response instanceof HttpServletResponse)) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (ServletFileUpload.isMultipartContent(httpRequest)) {
File repository = (File) this.getServletContext().getAttribute("javax.servlet.context.tempdir");
DiskFileItemFactory factory = new DiskFileItemFactory(0, repository);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(maxRequestSize);
List<FileItem> formItems = null;
try {
formItems = upload.parseRequest(httpRequest);
} catch (SizeLimitExceededException slee) {
throw new org.jboss.seam.web.FileUploadException("File size excededs maximum allowed.", slee);
} catch (FileUploadException fue) {
throw new org.jboss.seam.web.FileUploadException("Error uploading file.", fue);
}
Map<String, String> parameters = new HashMap<String, String>();
Map<String, File> fileParameters = new HashMap<String, File>();
if (formItems != null && formItems.size() > 0) {
for (FileItem item : formItems) {
if (item.isFormField()) {
parameters.put(item.getFieldName(), item.getString());
} else {
String fileName = item.getName();
// This is for IE7 (and Safari?) which sends the whole path.
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
if (!MyMultipartRequestUtils.isValidFileType(acceptedFileExtensions, fileName)) {
throw new org.jboss.seam.web.FileUploadException("The file type is not an accepted file type.");
}
File tempFile = null;
try {
tempFile = File.createTempFile(new UID().toString().replace(":", "-"), ".upload");
tempFile.deleteOnExit();
item.write(tempFile);
} catch (Exception e) {
throw new org.jboss.seam.web.FileUploadException("Error uploading file. Could not write file to server.");
}
fileParameters.put(fileName, tempFile);
}
}
}
MyMultipartRequestWrapper requestWrapper = new MyMultipartRequestWrapper(httpRequest, parameters, fileParameters);
chain.doFilter(requestWrapper, response);
} else {
chain.doFilter(request, response);
}
}
}
So, to reiterate, if I use the frame to upload files, everything works and the frame continues on the same conversation adding each child to the parent, if I upload a file that is too big, I get the correct message in the global message area of the frame, but the conversation get incremented and then the children are obviously being added to a new parent entity in the new conversation. Any help would be greatly appreciated.
I just ended up adding a field to my custom request wrapper to carry any exceptions I wanted to handle and then handled them in the
#{attachmentAction.addAttachment()}
action call further up the request chain. All works now, I just add my faces messages from there and the conversation does not get incremented the same as if I had a successful upload.
I'm using the design pattern found here. It has a FrontController, Command -> Service, and Dao.
If I load this URL in my browser (viewprofile is the name of the jsp):
http://localhost:8080/MyApplication/FrontController/viewprofile
I don't know how to automatically invoke ViewProfileCommand to then display the details of a user.
Currently the way I have it is like this, in order to invoke ViewProfileCommand I have to concatenate it onto the URL like: http://localhost:8080/MyApplication/FrontController/viewprofile?action=ViewProfile.
How do I map a jsp to a command without having to concatenate it onto the URL? Thanks
FrontController:
package com.secret.bookstore.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.secret.bookstore.command.Command;
import com.secret.bookstore.command.CommandFactory;
import com.secret.bookstore.exceptions.CommandCreationException;
import com.sun.net.httpserver.Filter.Chain;
/*
* Front Controller (Mediator Pattern)
*/
#WebServlet(urlPatterns={"/FrontController"})
public class FrontController extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
public FrontController(){
super();
}
protected void service(HttpServletRequest request, HttpServletResponse response){
String action = request.getParameter("action");
CommandFactory commandFactory = CommandFactory.getInstance();
Command command = null;
String view = null;
view = request.getPathInfo().substring(1);
if(action != null){
try {
command = commandFactory.createCommand(action);
view = command.execute(request, response);
} catch(CommandCreationException e) {
e.printStackTrace();
}
}
forwardToPage(request, response, view);
}
/**
* Forward to server to the supplied page
*/
private void forwardToPage(HttpServletRequest request, HttpServletResponse response, String view){
//Get the request dispatcher object and forward the request to the appropriate JSP page...
if(view.equals(request.getPathInfo().substring(1))){
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/" + view + ".jsp");
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
response.sendRedirect(view);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You have designed your front controller to determine actions based on request parameters instead of request path info. So you really have to supply a request parameter in order to invoke an action.
The front controller example in the linked answer determines the action based on request method and request path info which is also a more sensible way. You'd need to do the same in order to achieve your functional requirement of being able to preprocess GET requests.
Basically:
command = commandFactory.createCommand(request.getMethod(), request.getPathInfo());
or just as in the given example:
command = commandFactory.createCommand(request);