[JAVA] J'ai créé et défini mon propre dialecte avec Thymeleaf et j'ai essayé de l'utiliser

En raison des circonstances des projets auxquels nous avons participé, il y avait de nombreux comportements qui ne pouvaient pas être réalisés avec le standard standard direct seul, nous avons donc décidé de le mettre en œuvre nous-mêmes. En premier lieu, Thymeleaf lui-même n'avait pas beaucoup d'occasions de toucher depuis la formation quand j'étais un nouveau venu, mais j'étais plutôt familier avec JSP, donc j'ai commencé à étudier dès le début.

Cela est devenu de plus en plus amusant car j'ai pu le mettre en œuvre par essais et erreurs et reproduire l'opération prévue, je vais donc le laisser comme un mémorandum.

Qu'est-ce que Dialect en premier lieu?

Les types typiques qui sont essentiellement utilisés sont classés comme suit.

Nom La description
IProcessorDialect Direct qui fournit des éléments et des attributs
IExpressionObjectDialect Direct qui fournit des objets pouvant être utilisés dans les expressions EL dans les valeurs d'attribut de balise

IProcessorDialect enregistre un processeur et implémente des balises, et peut être utilisé avec une méthode de description telle que «th: text». IExpressionObjectDialect peut ajouter des utilitaires qui peuvent être utilisés dans des expressions EL, telles que «# strings».

Comment utiliser et créer votre propre dialecte

IProcessorDialect

Un dialecte qui peut être décrit comme un élément ou un attribut. Comme IProcessorDialect a une classe abstraite appelée AbstractProcessorDialect, nous en héritons et l'implémentons généralement. Créez un processeur qui implémente le traitement réel séparément et enregistrez-le dans la classe d'implémentation de AbstractProcessorDialect pour qu'il fonctionne.

Par exemple, si vous créez une date pour la mettre en forme sous la forme «aaaa / mm / jj», vous pouvez l'utiliser comme suit.

■ Description sur le modèle

<span thex:formatdate="${date}"></span>

■ Les éléments qui sont réellement sortis

<span>2020/01/01</span>

De plus, lorsque j'ai écrit le Dialect en ligne précédemment créé dans la balise de script, j'en étais accro car il n'était pas reconnu.

<script th:inline="javascript">
	var test =  [# thex:formatdate="${date}" /] ;
	console.log(test);
</script>

Il semble qu'il ne sera pas reconnu sur le modèle à moins que la description ne soit définie pour être reconnue en ligne dans l'implémentation de AbstractProcessorDialect. Par conséquent, il est nécessaire de définir le mode modèle en fonction du cas où JavaScript ou CSS est utilisé.

@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
  Set<IProcessor> proccessors = new HashSet<>();

  proccessors.add(new SampleProcesssor(TemplateMode.HTML, dialectPrefix));
  proccessors.add(new SampleProcesssor(TemplateMode.JAVASCRIPT, dialectPrefix));
  proccessors.add(new SampleProcesssor(TemplateMode.CSS, dialectPrefix));

  return proccessors;
}

IExpressionObjectDialect

À titre d'essai, nous allons implémenter ʻIExpressionObjectDialectet créer un utilitaire qui peut être utilisé dans les expressions EL en tant que# sample`. Veillez à ne pas dupliquer le nom que vous ajoutez en tant qu'utilitaire avec celui fourni en standard.

Tout d'abord, nous allons implémenter Dialog pour enregistrer l'objet Expression. Ici, nous allons générer le nom de l'utilitaire lors de son utilisation dans l'expression EL et la classe qui effectue réellement le traitement.

public class SampleDialect extends AbstractDialect implements IExpressionObjectDialect {

	//Nom des constantes lorsqu'elles sont utilisées dans les expressions EL
	private static final String SAMPLE_DIALECT_NAME = "sample";
	
	private static final Set<String> EXPRESSION_OBJECT_NAMES = Collections.singleton(SAMPLE_DIALECT_NAME);


	public SampleDialect() {
		super(SAMPLE_DIALECT_NAME);
	}
	
	@Override
	public IExpressionObjectFactory getExpressionObjectFactory() {
		return new IExpressionObjectFactory() {

			@Override
			public Set<String> getAllExpressionObjectNames() {
				return EXPRESSION_OBJECT_NAMES;
			}

			@Override
			public Object buildObject(IExpressionContext context, String expressionObjectName) {
				if (SAMPLE_DIALECT_NAME.equals(expressionObjectName)) {
					//Générer une classe qui traite comme un utilitaire
					return new Sample();
				}
				return null;
			}

			@Override
			public boolean isCacheable(String expressionObjectName) {
				return true;
			}

		};
	}

}

Ensuite, nous allons créer une classe qui transfère réellement le traitement du côté du modèle. Cette fois, nous allons l'implémenter avec un processus simple consistant à passer une chaîne de caractères, à la formater et à l'afficher à l'écran.

public class Sample {
	
	public String getSampleString(final String str) {
		return "Exemple de chaîne "" + str + "」";
	}

}

Vous pouvez en fait l'utiliser dans l'expression EL comme suit sur HTML.

■ Description sur le modèle

<span th:text="${#sample.getSampleString('échantillon')}"

■ Les éléments qui sont réellement sortis

<span>Exemple de chaîne de caractères "sample"</span>

Implémentation de la configuration sur Spring MVC

Définissez ViewResolver dans la classe de paramètres afin qu'il puisse fonctionner sur MVC. (Pour plus d'informations sur la mise en œuvre de Java Config, cliquez ici](https://qiita.com/HiroyaEnd/items/17175e947911d84c1b3b#webmvcconfig)) Puisque vous pouvez enregistrer votre propre dialecte ici, vous pouvez également l'enregistrer et le faire fonctionner sur le modèle. (La méthode de paramétrage est fondamentalement la même pour IProcessorDialect et IExpressionObjectDialect)

//Constantes utilisées pour les paramètres d'encodage
public static final String CHARACTER_ENCODING = "UTF-8";

//Constante du chemin du répertoire de base où se trouve le modèle
private static final String VIEW_LOCATION = "/WEB-INF/views/";


//Définition du haricot ThymeleafViewResolver
@Bean
public ThymeleafViewResolver viewResolver() {
	final ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
	thymeleafViewResolver.setTemplateEngine(templateEngine());
	thymeleafViewResolver.setCharacterEncoding(CHARACTER_ENCODING); //Définir le codage de la réponse
	
	return thymeleafViewResolver;
}

//Définir SpringTemplateEngine Bean
@Bean
public SpringTemplateEngine templateEngine() {
	final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
	templateEngine.setTemplateResolver(templateResolver());
	templateEngine.addDialect(new SampleDialect()); //Enregistrez votre propre dialecte

	return templateEngine;
}

//Définir TemplateResolver comme Bean
@Bean
public AbstractConfigurableTemplateResolver templateResolver() {
	final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
	templateResolver.setPrefix(VIEW_LOCATION); //Spécifiez le répertoire de base dans lequel le modèle Thymeleaf est stocké
	templateResolver.setSuffix(".html"); //Définir l'extension de modèle Thymeleaf
	templateResolver.setTemplateMode(TemplateMode.HTML); //Définir le mode modèle à interpréter(La valeur par défaut est le mode HTML, mais elle est explicitement définie)
	templateResolver.setCharacterEncoding(CHARACTER_ENCODING); //Définir l'encodage du fichier modèle
	
	return templateResolver;
}

Une fois l'implémentation du paramètre terminée, vous pouvez l'utiliser en créant un fichier modèle et en le transférant. Les paramètres ci-dessus ne sont que des exemples, je pense donc que vous devez les modifier en fonction de votre environnement.

Résumé

Quand je l'ai utilisé, il y avait de nombreux points que je pensais plus faciles à utiliser que JSP. J'ai trouvé intéressant qu'il soit hautement extensible car vous pouvez facilement ajouter votre propre dialecte, et qu'il peut être implémenté de manière flexible en le combinant avec Standard Direct. Personnellement, c'était plus facile à étendre que la balise d'origine de JSP.

Puisque Spring recommande Thymeleaf, il y aura probablement de nombreuses occasions d'entrer en contact avec lui à l'avenir, je voudrais donc approfondir mes connaissances. (De préférence freemaker ...)

référence

https://qiita.com/yoshikawaa/items/aba090f291f69185e6a5

https://macchinetta.github.io/server-guideline-thymeleaf/1.5.1.RELEASE/ja/ArchitectureInDetail/WebApplicationDetail/Thymeleaf.html#id21

Recommended Posts

J'ai créé et défini mon propre dialecte avec Thymeleaf et j'ai essayé de l'utiliser
J'ai essayé de créer mon propre guide de transfert en utilisant OpenTrip Planner et GTFS
J'ai essayé d'utiliser JOOQ avec Gradle
J'ai essayé d'utiliser Realm avec Swift UI
J'ai essayé d'utiliser Scalar DL avec Docker
J'ai essayé d'utiliser OnlineConverter avec SpringBoot + JODConverter
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
[Android] J'ai quitté SQLite et essayé d'utiliser Realm
J'ai aussi essayé Web Assembly avec Nim et C
J'ai fait un blackjack avec Ruby (j'ai essayé d'utiliser minitest)
J'ai essayé d'appeler une vidéo YouTube de DB avec haml et de l'afficher intégrée
J'ai essayé d'étudier le mécanisme d'Emscripten en l'utilisant avec un solveur allemand
J'ai essayé de lire et de sortir CSV avec Outsystems
J'ai démarré MySQL 5.7 avec docker-compose et j'ai essayé de me connecter
J'ai essayé d'utiliser YOLO v4 sur Ubuntu et ROS
J'ai essayé d'utiliser Gson
J'ai essayé d'utiliser TestNG
J'ai essayé d'utiliser Galasa
J'ai été piégé lorsque j'ai généré mes propres égaux de classe et hashCode en Java à l'aide de l'IDE
J'ai essayé un test unitaire de l'application Rails en utilisant RSpec et FactoryBot
J'ai mis à jour mon propre blackjack réalisé avec Ruby pour mon portfolio
J'ai essayé de démarrer avec Swagger en utilisant Spring Boot
J'ai essayé de résumer l'orientation de l'objet à ma manière.
J'ai essayé d'utiliser la bibliothèque CameraX avec Android Java Fragment
[Spring Boot] Je veux ajouter mon propre fichier de propriétés et obtenir la valeur avec env.getProperty ().
Lorsque j'ai essayé d'exécuter mon propre service, il a échoué, alors je l'ai vissé dans le planificateur de tâches
J'ai essayé DI avec Ruby
J'ai essayé d'utiliser azure cloud-init
J'ai essayé d'utiliser Apache Wicket
J'ai essayé d'utiliser Java REPL
J'ai essayé UPSERT avec PostgreSQL.
J'ai essayé BIND avec Docker
J'ai essayé d'imprimer un formulaire avec Spring MVC et Jasper Reports 3/3 (contrôle Spring MVC)
J'ai essayé d'intégrer parfaitement Docker et Maven / Netbean en utilisant Jib
J'ai essayé de me connecter à MySQL en utilisant le modèle JDBC avec Spring MVC
J'ai essayé d'en faire une URL arbitraire en utilisant l'imbrication de routage
Image de l'application Spring Boot à l'aide de jib-maven-plugin et lancez-la avec Docker
Je souhaite télécharger un fichier sur Internet en utilisant Ruby et l'enregistrer localement (avec prudence)