Archives par mot-clé : Java

Forcer le rechargement Javascript ou CSS

Parfois, un développeur peut éprouver quelques difficultés à forcer le rechargement d’une partie du site Web, sans pour autant ignorer le cache du navigateur.

Bien souvent, Internet Explorer pour n’en citer qu’un (mais sans doute le pire), continue de se baser sur une version obsolète d’un fichier Javascript, car présent dans son cache, ce parfois même en tentant de rafraîchir à grands coups de F5.

Pour forcer le navigateur à recharger un fichier fraîchement mis à jour, il suffit en fait de modifier son URL, en ajoutant un attribut derrière le « ? ». Dans ce cas, pourquoi ne pas se baser sur la date de modification du-dit fichier pour générer cet attribut ? C’est justement ce que le bout de code ci-dessous permet de faire depuis une JSP.

<%
	final String CSS = "css/main.css";
	final String JS = "js/main.js";
	final String ABSOLUTE_PATH = request.getSession().getServletContext().getRealPath(".") + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr-FR" lang="fr-FR">
<head>
	<title>Date de modification d'un fichier depuis une JSP</title>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<meta http-equiv="content-language" content="fr-FR" />
	<meta name="language" content="fr-FR" />
	<link rel="stylesheet" type="text/css" href="<%= CSS + "?" + (new java.io.File(ABSOLUTE_PATH + CSS)).lastModified() %>" />
	<script type="text/javascript" src="<%= JS + "?" + (new java.io.File(ABSOLUTE_PATH + JS)).lastModified() %>"></script>
...

Attention ! Si votre page Web est présente dans un sous-répertoire de la racine du site, pensez à ajouter ce sous-répertoire derrière le slash final dans la constante ABSOLUTE_PATH, comme ceci : / --> /sous-repertoire/
Dans le cas contraire, aucune Exception ne sera provoquée lors de l’exécution du Servlet, mais la méthode lastModified() se contentera de retourner 0 pour un fichier qui n’a tout simplement pas été trouvé.

Produire un fichier CSV à partir d’une JSP

Les différences entre les navigateurs, mais aussi entre les numéros de version des navigateurs, sont la source de nombreux problèmes quand il s’agit de développer une fonction a priori simple. Produire un vulgaire fichier CSV à la volée via une JSP en est le parfait exemple : si l’on se contente d’écrire le contenu directement dans le flux de sortie out (e.g. « <%= maVariable %> » ), aucune version d’Internet Explorer antérieure à la 9 n’est en mesure de télécharger correctement le fichier produit. Pour ce faire, et ce n’est pas moi qui ai trouvé la solution mais mon chef *, il est nécessaire de passer par un StringBuffer et d’écrire l’ensemble du flux via le Writer de l’instance response.

<%@ page contentType="application/octet-stream" import="java.util.*, java.io.*" %><%
	response.setContentType("application/vnd.ms-excel");
	response.setHeader("Content-Disposition", "attachment; filename=\"donnees.csv\"");
	
	final String sep = ";"; // separateur de colonnes a la Excel
	final String crlf = "\r\n"; // fin de ligne a la ouin-ouin

	StringBuffer stringBuffer = new StringBuffer();
	
	stringBuffer.append("Chaine" + sep + "Nombre" + crlf);
	stringBuffer.append("\"Hello world\"" + sep + "123,45" + crlf);
	
	PrintWriter pw = response.getWriter();
	pw.println( stringBuffer.toString() );
%>

* Les chefs, c’est aussi fait pour ça !

Coder en Java avec Notepad++

Notepad++ est une des références en terme d’éditeur de texte à coloration syntaxique pour ouin-ouinWindows. La pléthore de fonctionnalités qu’il possède, et sa capacité à être étendu par de nombreux greffons, en font un outil presque incontournable. Bien entendu, il s’agit d’un logiciel Libre !

Malgré toutes ses années, le greffon Function List souffre toujours de petits manques, en particulier pour son utilisation avec les sources Java. Pour pallier ce problème, j’ai fini par écrire un certain nombre de règles (vive les expressions régulières !) afin de les ajouter dans son fichier de configuration C:Users…AppDataRoamingNotepad++pluginsconfigFunctionListRules.xml (en prenant soin de remplacer la balise « Language » déjà existante pour le langage Java).

<Language name="Java" imagelistpath="plugins\Config\Java.bmp">
	<CommList param1="//" param2="" />
	<CommList param1="/\*" param2="\*/" />
	<CommList param1='\"' param2='\"' />
	<Group name="CLASSES" subgroup="" icon="1" child="0" autoexp="0" matchcase="1" fendtobbeg="\}" bbegtobend="\{" keywords="">
		<Rules regexbeg="\w*\s*class\s+" regexfunc="\w+\s*" regexend="[^\{]*" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="\w*\s*static\s+class\s*" regexfunc="\w+\s*" regexend="[^\{]*" bodybegin="" bodyend="" sep="" />
	</Group>
	<Group name="CONSTANTS" subgroup="" icon="3" child="0" autoexp="0" matchcase="1" fendtobbeg="\}" bbegtobend="\{" keywords="">
		<Rules regexbeg="\w*\s*final\s+static\s+\w+\s*" regexfunc="\w+" regexend="\s*=" bodybegin="" bodyend=";" sep="" />
		<Rules regexbeg="\w*\s*final\s+static\s+\w+<.+>\s*" regexfunc="\w+" regexend="\s*=" bodybegin="" bodyend=";" sep="" />
	</Group>
	<Group name="VARIABLES" subgroup="" icon="3" child="0" autoexp="0" matchcase="1" fendtobbeg="\}" bbegtobend="\{" keywords="final|static">
		<Rules regexbeg="private\s+[\w\.\[\]]+\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="protected\s+[\w\.\[\]]+\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="public\s+[\w\.\[\]]+\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="protected\s+[\w\.\[\]]+<.+>\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="public\s+[\w\.\[\]]+<.+>\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
		<Rules regexbeg="private\s+[\w\.\[\]]+<.+>\s+" regexfunc="\w+\s*" regexend="=*[^\(]*;" bodybegin="" bodyend="" sep="" />
	</Group>
	<Group name="METHODS" subgroup="" icon="4" child="0" autoexp="0" matchcase="1" fendtobbeg="\}" bbegtobend="\{" keywords="else|new|return">
		<Rules regexbeg="\w+\s*\[*\]*\s+" regexfunc="\w+\s*" regexend="\([^\(]*\)\s*" bodybegin="\{" bodyend="\}" sep="" />
		<Rules regexbeg="abstract\s*\w*\s*\w*\s*" regexfunc="\w+\s*" regexend="\([^\(]*\)\s*" bodybegin="" bodyend=";" sep="" />
		<Rules regexbeg="\w+\s*<.+>\s+" regexfunc="\w+\s*" regexend="\([^\(]*\)\s*" bodybegin="\{" bodyend="\}" sep="" />
		<Rules regexbeg="abstract\s*\w*\s*\w*\s*<.+>\s*" regexfunc="\w+\s*" regexend="\([^\(]*\)\s*" bodybegin="\{" bodyend="\}" sep="" />
	</Group>
</Language>

Il est à noter que ces règles sont directement éditables depuis Notepad++. Pour ce faire, le menu Compléments > Function List > Language Parsing Rules ouvre une boîte de dialogue facilitant l’ajout, la suppression et la modification de ces règles, ainsi que (et c’est là que réside tout son intérêt !) leur débogage via le bouton « Try! » .

En reprenant le fichier C:Program FilesNotepad++pluginsConfigC++.flb, qui n’est autre qu’une image BMP avec une extension bizarre… 😕 il est possible de définir de petites icônes pour chaque type d’objet. Le fichier est en effet constitué de 20 petites images de 16 pixels de côté, numérotées de 0 à 19. Ainsi, il est possible de modifier l’icône d’une balise « Group » en changeant le numéro d’image dans l’attribut icon de celle-ci. En revanche, chaque entrée trouvée par Function List conservera pour icône l’image numérotée 0, qui correspond à une petite feuille avec la lettre C… ce qui n’est pas très Java-friendly… Dans ce cas, pourquoi ne pas faire une copie du fichier C++.flb en tant que Java.bmp, et l’éditer avec l’outil Paint de ouin-ouinWindows ou un logiciel tel que Gimp ?

Fichier C++.flb modifié en Java.bmp
Le résultat sera, à n’en pas douter, du plus bel effet, sans compter le caractère indispensable que prendra votre liste de classes, de méthodes et autres variables !