I'm creating a maven project, and i try to display image from my computer but JSP do not allow it.
So after search on Stackoverflow i got a solution is using FileServlet to handle it,
but after try it, i still can not get image to display, so please help me
this is my code:
FileServlet.java
package fileServer;
import java.io.*;
import java.net.URLDecoder;
import javax.servlet.*;
import javax.servlet.http.*;
public class FileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private String filePath;
/**
* #see HttpServlet#HttpServlet()
*/
public FileServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
public void init() throws ServletException {
// Define base path somehow. You can define it as init-param of the
// servlet.
this.filePath = "F:\\DrugStore\\Medicine";
// In a Windows environment with the Applicationserver running on the
// c: volume, the above path is exactly the same as "c:\files".
// In UNIX, it is just straightforward "/files".
}
protected final void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("In do get");
// Get requested file by path info.
String requestedFile = request.getPathInfo();
// Check if file is actually supplied to the request URI.
if (requestedFile == null) {
// Do your thing if the file is not supplied to the request URI.
// Throw an exception, or send 404, or show default/warning page, or
// just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Decode the file name (might contain spaces and on) and prepare file
// object.
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));
// Check if file actually exists in filesystem.
if (!file.exists()) {
// Do your thing if the file appears to be non-existing.
// Throw an exception, or send 404, or show default/warning page, or
// just ignore it.
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}
// Get content type by filename.
String contentType = getServletContext().getMimeType(file.getName());
// If content type is unknown, then set the default value.
// For all content types, see:
// http://www.w3schools.com/media/media_mimeref.asp
// To add new content types, add new mime-mapping entry in web.xml.
if (contentType == null) {
contentType = "application/octet-stream";
}
// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\""
+ file.getName() + "\"");
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
// Open streams.
input = new BufferedInputStream(new FileInputStream(file),
DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(),
DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
// Gently close streams.
close(output);
close(input);
}
}
protected final void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("In do post");
}
private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
// Do your thing with the exception. Print it, log it or mail
// it.
e.printStackTrace();
}
}
}
}
web.xml
<servlet>
<display-name>fileServlet</display-name>
<servlet-name>fileServlet</servlet-name>
<servlet-class>fileServer.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileServlet</servlet-name>
<url-pattern>/fileServlet</url-pattern>
</servlet-mapping>
index.jsp
<td colspan="2"><img src="fileServlet?path=${pr.imgname}" /></td>
thank for help
I am not clearly know how you code is write,but I guess all your jsp page are in the WEB-INF folder,and can only be accessed via springMVC request.This is due to the spring dispatcher filter,in order to let the static resource to be exclude of the filter,you can add the static file type to the default servlet mapping as below:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.bmp</url-pattern>
</servlet-mapping>
Related
I'm trying to add custom tags - the path variables and their values from each request - to each metric micrometer generates. I'm using spring-boot with java 16.
From my research i've found that creating a bean of type WebMvcTagsContributor alows me to do just that.
This is the code
public class CustomWebMvcTagsContributor implements WebMvcTagsContributor {
private static int PRINT_ERROR_COUNTER = 0;
#Override
public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response,
Object handler,
Throwable exception) {
return Tags.of(getAllTags(request));
}
private static List<Tag> getAllTags(HttpServletRequest request) {
Object attributesMapObject = request.getAttribute(View.PATH_VARIABLES);
if (isNull(attributesMapObject)) {
attributesMapObject = request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
if (isNull(attributesMapObject)) {
attributesMapObject = extractPathVariablesFromURI(request);
}
}
if (nonNull(attributesMapObject)) {
return getPathVariablesTags(attributesMapObject);
}
return List.of();
}
private static Object extractPathVariablesFromURI(HttpServletRequest request) {
Long currentUserId = SecurityUtils.getCurrentUserId().orElse(null);
try {
URI uri = new URI(request.getRequestURI());
String path = uri.getPath(); //get the path
UriTemplate uriTemplate = new UriTemplate((String) request.getAttribute(
HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)); //create template
return uriTemplate.match(path); //extract values form template
} catch (Exception e) {
log.warn("[Error on 3rd attempt]", e);
}
return null;
}
private static List<Tag> getPathVariablesTags(Object attributesMapObject) {
try {
Long currentUserId = SecurityUtils.getCurrentUserId().orElse(null);
if (nonNull(attributesMapObject)) {
var attributesMap = (Map<String, Object>) attributesMapObject;
List<Tag> tags = attributesMap.entrySet().stream()
.map(stringObjectEntry -> Tag.of(stringObjectEntry.getKey(),
String.valueOf(stringObjectEntry.getValue())))
.toList();
log.warn("[CustomTags] [{}]", CommonUtils.toJson(tags));
return tags;
}
} catch (Exception e) {
if (PRINT_ERROR_COUNTER < 5) {
log.error("[Error while getting attributes map object]", e);
PRINT_ERROR_COUNTER++;
}
}
return List.of();
}
#Override
public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
return null;
}
}
#Bean
public WebMvcTagsContributor webMvcTagsContributor() {
return new CustomWebMvcTagsContributor();
}
In order to test this, i've created a small spring boot app, added an endpoint to it. It works just fine.
The problem is when I add this code to the production app.
The metrics generates are the default ones and i can't figure out why.
What can I check to see why the tags are not added?
local test project
http_server_requests_seconds_count {exception="None", method="GET",id="123",outcome="Success",status="200",test="test",uri="/test/{id}/compute/{test}",)1.0
in prod - different (& bigger) app
http_server_requests_seconds_count {exception="None", method="GET",outcome="Success",status="200",uri="/api/{something}/test",)1.0
What i've tried and didn't work
Created a bean that implemented WebMvcTagsProvider - this one had an odd behaviour - it wasn't creating metrics for endpoints that had path variables in the path - though in my local test project it worked as expected
I added that log there in order to see what the extra tags are but doesn't seem to reach there as i don't see anything in the logs - i know, you might say that the current user id stops it, but it's not that.
I am new in Spring-Boot...
I want to upload images or videos, and store them in a persistant folder "upload-storage" in the class-path of my project in the server. I don't want to store them in the database (20 Mo).
Spring-Boot store them in target/upload-storage.
That functions : I can show the videos on the view with the controller and Thymeleaf. I can close tomcat, close the browser, and open them again : that functions.
But the day after, upload-storage is disapeared !
I think that I don't use the good process.
But I found how to upload an image : ok. I found how to show images from a folder in class-path : ok. I found how to upload images to database. But nothing to store the uploaded images in a persistant folder.
Can you help me ? Can you tell me the good process ?
Some details :
I have an entity "video" to store name, extension, length,... of the video.
I have "VideoRepository" and "VideoService" to manage the requests with "Video".
I have a "StorageService" and "StorageServiceImpl" to manage the upload of video and images : It as to upload the video and save it in a folder called "upload-storage" : I will come back on it farther.
I have a videoForm.html first with a form to select a file and send it to "UploadController", then an other form to show the video, the datas extracted from the video, modify the name or add precisions, and send this form to a "VideoController" who save the entity.
A part of the code of "UploadController" :
`
#Controller
public class UploadController extends BaseController {
private final StorageService storageServiceImpl;
#Autowired
public UploadController(StorageService storageServiceImpl) {
this.storageServiceImpl = storageServiceImpl;
}
#PostMapping("/upload")
public String recupereUpload(#RequestParam("file") MultipartFile file,Model model){
String filename ="";
try {
final long limit = 200 * 1024 * 1024;
if (file.getSize() > limit) {
model.addAttribute("message", "Taille du fichier trop grand (>200MB)");
model.addAttribute("ok", false );
}
filename = storageServiceImpl.store(file);
model.addAttribute("filename", filename);
model.addAttribute("message", "Le téléchargement de " + filename+" est réussi !");
} catch (Exception e) {
model.addAttribute("message", "FAIL to upload " + filename + "!");
model.addAttribute("ok", false );
}
Video video = new Video();
model.addAttribute("ok", true );
model.addAttribute("video", video);
String baseName = storageServiceImpl.getBaseName(filename);
String ext = storageServiceImpl.getExtension(filename);
model.addAttribute("nom", baseName);
model.addAttribute("ext", ext);
model.addAttribute("nomorigin", filename);
model.addAttribute("size", Math.round(file.getSize()/1024));
String typExt = storageServiceImpl.getType(ext);
model.addAttribute("typExt", typExt);
return "elementVideo/videoForm";
}
`
"StorageServiceImpl" has different methods :
getExtension(String filename){...}
getType(String ext){...}
getType(String ext){...}
getBaseName(String filename){...}
The main method is store(MultipartFile file) {...} :
#Service
public class StorageServiceImpl implements StorageService {
private final Path storageLocation = Paths.get("upload-storage");
#Override
public String store(MultipartFile file) {
try {
// Vérification de l'existence :
if (file.isEmpty()) {
throw new Exception("Failed to store empty file " + file.getOriginalFilename() );
}
// Vérification de la nature et traitement du fichier uploadé :
String ext = getExtension(file.getOriginalFilename());
String[] extAutorise = {"mp4", "avi","ogg","ogv","jpg","jpeg","png","gif"};
String fileNameTarget ="";
if ( ArrayUtils.contains( extAutorise, ext)) {
//Définir le fichier destination :
fileNameTarget = file.getOriginalFilename();
fileNameTarget = fileNameTarget.replaceAll(" ", "_");
File dir = storageLocation.toFile();
String serverFile = dir.getAbsolutePath() + File.separator + fileNameTarget ;
try {
try (InputStream is = file.getInputStream();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile))
) {
int i;
while ((i = is.read()) != -1) {
stream.write(i);
}
stream.flush();
}
} catch (IOException e) {
System.out.println("error : " + e.getMessage());
}
}
return fileNameTarget;
} catch (Exception e) {
throw new RuntimeException("FAIL!");
}
}
`
With this code, a folder "upload-storage" is created at the root of the project.
The video is uploaded in this folder...
But in "videoForm.html", the code
<video id="video" th:src="'/upload-storage/'+${filename}" height="60"
autoplay="autoplay"></video>
shows nothing.
I have an other solution.
In StorageServiceImpl, I use the code :
private final String storageLocation = this.getClass().getResource("/static/").getPath();
at place of :
private final Path storageLocation = Paths.get("upload-storage");
then :
File dir = new File(storageLocation + File.separator + "upload-storage");
at place of :
File dir = storageLocation.toFile();
then :
File serverFile = new File(dir.getAbsolutePath() + File.separator + fileNameTarget);
at place of :
String serverFile = dir.getAbsolutePath() + File.separator + fileNameTarget ;
With this solution, upload-storage is created in target folder.
I use an other controller BaseController :
public class BaseController {
public static final String PARAM_BASE_URL = "baseURL";
public String getBaseURL(HttpServletRequest request){
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}
}
`
UploadController extends this BaseController.
I add HttpServletRequest request in recupereUpload() :
#PostMapping("/upload")
public String recupereUpload(#RequestParam("file") MultipartFile file,
Model model, HttpServletRequest request ){
I add in the model sent by recupereUpload :
model.addAttribute(PARAM_BASE_URL, getBaseURL(request));
And at last, I can see my video in videoForm.html with the code :
<video id="video" th:src="${baseURL}+'/upload-storage/'+${filename}" height="60" autoplay="autoplay"></video>
I can close Tomcat, close Eclipse, close the machine, and open all again : all is preserved and I can see the video.
But some time later : all is disappeared.
There must be a better solution.
Can you help me ?
Why dont you use Spring Content for the video content portion of your solution? That way you won't need to implement any of the video content handling. Spring Content will provide this for you. To add Spring Content to your project:
Add Spring Content to your classpath.
pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>content-fs-spring-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
Associate content with your Video entity.
Video.java
#Entity
public class Video {
...
#ContentId
private String contentId;
#ContentLength
private Long contetLen;
#MimeType
private String mimeType;
...
Set up a "persistent folder" as the root of your video store. This is where uploaded videos will be stored/streamed from. Also create a VideoStore interface to describe to SC how you want to associate your content.
SpringBootApplication.java
#SpringBootApplication
public class YourSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(YourSpringBootApplication.class, args);
}
#Configuration
#EnableFilesystemStores
public static class StoreConfig {
File filesystemRoot() {
return new File("/path/to/your/videos");
}
#Bean
public FileSystemResourceLoader fsResourceLoader() throws Exception {
return new FileSystemResourceLoader(filesystemRoot().getAbsolutePath());
}
}
#StoreRestResource(path="videos")
public interface VideoStore extends ContentStore<Video,String> {
//
}
}
This is all you need to create a REST-based video service at /videos. Essentially, when your application starts, Spring Content will look at your dependencies (seeing Spring Content FS/REST), look at your VideoStore interface and inject an implementation of that interface based on the filesystem. It will also inject a controller that forwards http requests to that implementation as well. This saves you having to implement any of this yourself.
So...
POST /videos/{video-entity-id}
with a multipart/form-data request will store the video in /path/to/your/videos and associate it with the video entity whose id is video-entity-id.
GET /videos/{video-entity-id}
will fetch it again. This supports partial content requests or byte ranges; i.e. video streaming too.
and so on...support full CRUD.
There are a couple of getting started guides here. The reference guide is here. And there is a tutorial video here. The coding bit starts about 1/2 way through.
HTH
Did you enable the upload by adding the following property in the application.properties file?
## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
I have written an article about how to upload a multipart file in spring boot using thymeleaf. Here is the service used for the upload.
package com.uploadMultipartfile.storage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
#Service
public class FileSystemStorageService implements StorageService
{
private final Path rootLocation;
#Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getUploadDir()).toAbsolutePath().normalize();
try {
Files.createDirectories(this.rootLocation);
} catch (Exception ex) {
throw new StorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
#Override
public String store(MultipartFile file)
{
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try
{
if (file.isEmpty())
{
throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
}
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.rootLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
}
catch (IOException e)
{
throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
}
}
#Override
public void init()
{
try
{
Files.createDirectory(rootLocation);
}
catch (IOException e)
{
throw new StorageException("Could not initialize storage", e);
}
}
}
Here is a link to get the code of the application. http://mkaroune.e-monsite.com/pages/spring/spring-boot-multipart-file-upload.html
I can download data via HttpUrlConnection and InputStream but I need to download raw-data. So, i want to create a DownloadManager via raw-data, then using raw-data I convert this data to binary or image format. According to my research, I see "download file from url" but I can't download file in mac? Always, I get FileNotFoundException. Please help me. How I can download data from url?
public class DownloadData extends AsyncTask<Void,Void,Void> {
#Override
protected Void doInBackground(Void... params) {
try {
downloadData("https://blablalabla/get");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void downloadData(String myurl) throws IOException {
URL u = new URL(myurl);
InputStream is = u.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[1024];
int length;
OutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/Users/ilknurpc/Desktop/text.docx"));
while ((length = dis.read(buffer))>0) {
fos.write(buffer, 0, length);
}
}
}
If you want to construct a workable download manager, I would suggest that you take a look at the
Tomcat Default Servlet Implementation
.
There a few number of HTTP headers that you need to understand such as E-Tags and Http Range Headers for a proper implementation.
Thankfully the Tomcat Default Servlet handles the prerequisites for you.
You can adapt this servlet in your code with minor changes (package declaration etc).
I am using httpcomponenets nio server to handle post request.
Below is the sample code. It gets the complete data in byte array using EntityUtils.toByteArray(). This fails if the requester sends a large file.
I couldnt figure out how to read the data in the request in chunks.
HttpEntity.getContent().read() always returns null
public static void main(String[] args) throws Exception {
int port = 8280;
// Create HTTP protocol processing chain
HttpProcessor httpproc = HttpProcessorBuilder.create()
.add(new ResponseDate())
.add(new ResponseServer("Test/1.1"))
.add(new ResponseContent())
.add(new ResponseConnControl()).build();
// Create request handler registry
UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper();
// Register the default handler for all URIs
reqistry.register("/test*", new RequestHandler());
// Create server-side HTTP protocol handler
HttpAsyncService protocolHandler = new HttpAsyncService(httpproc, reqistry) {
#Override
public void connected(final NHttpServerConnection conn) {
System.out.println(conn + ": connection open");
super.connected(conn);
}
#Override
public void closed(final NHttpServerConnection conn) {
System.out.println(conn + ": connection closed");
super.closed(conn);
}
};
// Create HTTP connection factory
NHttpConnectionFactory<DefaultNHttpServerConnection> connFactory;
connFactory = new DefaultNHttpServerConnectionFactory(
ConnectionConfig.DEFAULT);
// Create server-side I/O event dispatch
IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory);
// Set I/O reactor defaults
IOReactorConfig config = IOReactorConfig.custom()
.setIoThreadCount(1)
.setSoTimeout(3000)
.setConnectTimeout(3000)
.build();
// Create server-side I/O reactor
ListeningIOReactor ioReactor = new DefaultListeningIOReactor(config);
try {
// Listen of the given port
ioReactor.listen(new InetSocketAddress(port));
// Ready to go!
ioReactor.execute(ioEventDispatch);
} catch (InterruptedIOException ex) {
System.err.println("Interrupted");
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
System.out.println("Shutdown");
}
public static class RequestHandler implements HttpAsyncRequestHandler<HttpRequest> {
public void handleInternal(HttpRequest httpRequest, HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
HttpEntity entity = null;
if (httpRequest instanceof HttpEntityEnclosingRequest)
entity = ((HttpEntityEnclosingRequest)httpRequest).getEntity();
byte[] data;
if (entity == null) {
data = new byte [0];
} else {
data = EntityUtils.toByteArray(entity);
}
System.out.println(new String(data));
httpResponse.setEntity(new StringEntity("success response"));
}
#Override public HttpAsyncRequestConsumer<HttpRequest> processRequest(HttpRequest request, HttpContext context) throws HttpException, IOException {
return new BasicAsyncRequestConsumer();
}
#Override
public void handle(HttpRequest request, HttpAsyncExchange httpExchange, HttpContext context) throws HttpException, IOException {
HttpResponse response = httpExchange.getResponse();
handleInternal(request, response, context);
httpExchange.submitResponse(new BasicAsyncResponseProducer(response));
}
}
Please consider implementing a custom AbstractAsyncRequestConsumer instead of BasicAsyncRequestConsumer if you want to have full control over request processing.
You might use these classes as a starting point [1][2]. Please note these are response consumers though one can use the same approach to create custom request consumers:
[1] http://hc.apache.org/httpcomponents-asyncclient-4.1.x/httpasyncclient/xref/org/apache/http/nio/client/methods/AsyncCharConsumer.html
[2] http://hc.apache.org/httpcomponents-asyncclient-4.1.x/httpasyncclient/xref/org/apache/http/nio/client/methods/AsyncByteConsumer.html
My question is very simple. I want to use another taglib with freemarker.
I read in the freemarker doc that it's possible.
I want to use the kendoui taglib
<%#taglib prefix="kendo" uri="http://www.kendoui.com/jsp/tags"%>
the api doc says we must do that by adding a line like
<#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]>.
But when i do that, i have the error
The following has evaluated to null or missing: ==> JspTaglibs
cordially.
thankyou for your answerd. it works thine when i use freemarkerServlet.
But i want to use a single servlet that will allow me to configure freemarker (in init method) and parse the html response to response writer.
req.setCharacterEncoding(cfg.getOutputEncoding());
resp.setContentType("text/html; charset=" + cfg.getOutputEncoding());
resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Expires", "Thu, 01 Dec 1994 00:00:00 GMT");
Writer out = resp.getWriter();
template.process(page.getRoot(), out);
in fact, i want to extend freemarkerServlet class as mentionned here : http://schakrap.wordpress.com/2009/09/05/using-freemarkerservlet-in-google-guice-to-inject-configuration/ .
But i still have the same error.
for the matter what does mean the config parameter TemplatePath ?
The JspTaglibs variable, and the whole environment that's needed for custom JSP tags to feel home, is set up by the freemarker.ext.servlet.FreemarkerServlet. So currently the only way to use taglibs is with FreemarkerServlet, which was made so that you can use FTL files instead of JSP files in legacy JSP Model-2 frameworks.
package presentation;
import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.text.DateFormat;
import java.util.Locale;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import freemarker.core.Macro;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
public class ControllerServlet extends freemarker.ext.servlet.FreemarkerServlet
{
//
private Configuration cfg;
private Handler handler;
public ControllerServlet()
{
super();
}
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
String userAgentString = "";
StringBuffer url = req.getRequestURL();
String sUrl = url.toString();
// on instancie les classes/structures pour Freemarker
FreemarkerParameterMap page = new FreemarkerParameterMap();
handler = new Handler();
try
{
userAgentString = req.getHeader("User-Agent");
System.out.println("User-Agent : " + userAgentString);
handler.handle(req, resp, page);
if (page.getDataType() == FreemarkerParameterMap.AJAX_JSON)
{
Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL).setPrettyPrinting().create();
Map<String, Object> map = page.getRoot();
resp.setContentType("application/json;charset=UTF-8");
resp.getWriter().println(gson.toJson(map));
resp.getWriter().flush();
}
else if (page.getDataType() == FreemarkerParameterMap.HTML_REDIRECT && page.getRedirect() != null)
{
resp.sendRedirect(page.getRedirect());
}
else if (page.getDataType() == FreemarkerParameterMap.HTML_FORWARD && page.getForward() != null)
{
RequestDispatcher rd = req.getRequestDispatcher(page.getForward());
rd.forward(req, resp);
}
else
{
if (page.getTemplate() != null)
{
Template t = cfg.getTemplate("theme/" + page.getTemplate());
if (page.getDataType() == FreemarkerParameterMap.AJAX_HTML)
{
Map mapMacro = t.getMacros();
Macro macro = (Macro) mapMacro.get(page.getMacro());
t = new Template("name", new StringReader(macro.getSource()+"<#"+page.getMacro()+"/>"), cfg);
}
else if (page.getDataType() == FreemarkerParameterMap.HTML)
{
}
req.setCharacterEncoding(cfg.getOutputEncoding());
resp.setContentType("text/html; charset=" + cfg.getOutputEncoding());
resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Expires", "Thu, 01 Dec 1994 00:00:00 GMT");
Writer out = resp.getWriter();
t.process(page.getRoot(), out);
}
else
{
throw new ServletException("aucune action specifiée");
}
}
}
/*catch (EcoliaException e)
{
} */
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* #param request the request send by the client to the server
* #param response the response send by the server to the client
* #throws ServletException if an error occurred
* #throws IOException if an error occurred
*/
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
doGet(req, resp);
}
/**
* Initialization of the servlet. <br>
*
* #throws ServletException if an error occurs
*/
public void init() throws ServletException
{
// Initialize the FreeMarker configuration;
// - Create a configuration instance
cfg = new Configuration();
// - Templates are stored in the WEB-INF/templates directory of the Web app.
cfg.setServletContextForTemplateLoading(getServletContext(), "");
// - Set update dealy to 0 for now, to ease debugging and testing.
// Higher value should be used in production environment.
cfg.setTemplateUpdateDelay(0);
// - Set an error handler that prints errors so they are readable with
// a HTML browser.
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
// - Use beans wrapper (recommmended for most applications)
cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
// - Set the default charset of the template files
cfg.setDefaultEncoding("UTF-8");
// - Set the charset of the output. This is actually just a hint, that
// templates may require for URL encoding and for generating META element
// that uses http-equiv="Content-type".
cfg.setOutputEncoding("UTF-8");
// - Set the default locale
cfg.setLocale(Locale.US);
System.out.println("init controleur");
}
}
and in the web.xml i have this :
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>ControllerServlet</servlet-name>
<servlet-class>presentation.ControllerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ControllerServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>