La campagne GoToEat a débuté en octobre. L'utilisez-vous? Campagne GoToEat du Ministère de l'agriculture, des forêts et de la pêche
J'avais l'habitude de l'utiliser souvent, mais il semble que "Mugenkura Sushi" soit populaire dans les rues. Vous pouvez manger aux points que vous obtenez avec GoToEat, et vous pouvez à nouveau obtenir des points avec ce repas, de sorte que vous pouvez manger des sushis Kura plusieurs fois à un bon prix. (Mis à part l'histoire morale) Page officielle de la campagne GoToEat de Kurasushi
Afin de recevoir des points chez GoToEat, il faut manger au moins 500 yens TTC pour le déjeuner et 1000 yens TTC pour le dîner chez Kura Sushi. Par conséquent, j'ai fait "Mugen Kura Sushi Gacha" qui est affiché aléatoirement sur le menu de Kura Sushi quand il dépasse le prix correspondant.
Cliquez ici pour l'application web que j'ai créée ↓ ** Mugenkura Sushi Gacha **
Cette fois, j'ai utilisé le framework "Spring Boot". Le code complet est disponible sur github ↓ https://github.com/yutwoking/eternalKurazushi
Je laisserai cet article comme une étape dans la création de ces applications à l'avenir.
Partie du framework Spring Boot --build.gradle description --Création d'un lanceur --Création d'un contrôleur --html creation (création de vue)
Publication d'applications Web (AWS)
Tout d'abord, chargez le menu depuis le site officiel. Il est nécessaire d'analyser le html du Site officiel du menu. Analysez à l'aide d'une bibliothèque appelée Jsoup.
Comment utiliser la référence Jsoup https://www.codeflow.site/ja/article/java-with-jsoup
La mise en œuvre de la partie analyse est la suivante
LoadMenu.java
private static List<MenuModel> loadMenuFromSite(String url) throws IOException{
List<MenuModel> models = new LinkedList<>();
Document doc = Jsoup.connect(url).get();
Elements menusBySection = doc.select(".section-body");
for (Element section : menusBySection) {
String sectionName = section.select(".menu-section-header h3").text();
if (!StringUtils.isEmpty(sectionName)) {
Elements menus = section.select(".menu-list").get(0).select(".menu-item");
for (Element menu : menus) {
String name = menu.select(".menu-name").text();
Elements summary = menu.select(".menu-summary li");
if (summary.size() >2) {
int price = stringToInt(summary.get(0).select("p").get(0).text());
int kcal = stringToInt(summary.get(0).select("p").get(1).text());
String area = summary.get(1).select("p").get(1).text();
boolean takeout = toBoolean(summary.get(2).select("p").get(1).text());
models.add(new MenuModel(name, price, kcal, area, takeout, sectionName));
} else if (summary.size() == 2) {
int price = stringToInt(summary.get(0).select("p").get(0).text());
int kcal = stringToInt(summary.get(0).select("p").get(1).text());
String area = "";
boolean takeout = toBoolean(summary.get(1).select("p").get(1).text());
models.add(new MenuModel(name, price, kcal, area, takeout, sectionName));
}
}
}
}
return models;
}
En tant qu'utilisation de base de JSoup,
Document doc = Jsoup.connect(url).get();
Lire l'url html avec
Elements elements = doc.select(".section-body");
Utilisez la méthode de sélection comme celle-ci pour extraire l'élément pertinent.
Je regrette que le code d'implémentation soit difficile à voir car les instructions if et for sont imbriquées. .. ..
Vient ensuite l'implémentation autour de la base de données. J'utilise un framework d'accès java DB appelé Doma2. Cliquez ici pour le fonctionnaire Doma2
Doma présente les caractéristiques suivantes.
· Utiliser le traitement des annotations pour générer et valider le code au moment de la compilation · Peut mapper les valeurs de colonne de la base de données sur des objets Java comportementaux ・ Un modèle SQL appelé SQL bidirectionnel peut être utilisé. -Java 8 java.time.LocalDate, java.util.Optional et java.util.stream.Stream peuvent être utilisés. -Pas de dépendance vis-à-vis des bibliothèques autres que JRE
C'est un framework que j'utilise souvent car j'aime personnellement le fait qu'il puisse être géré avec des fichiers sql. L'usage est officiel et japonais, il est donc bon de s'y référer. Le code d'implémentation est omis ici. Le code complet est disponible sur github ↓ https://github.com/yutwoking/eternalKurazushi
Gacha.java
public static List<MenuModelForSearch> getResult(Areas area, boolean isLunch){
List<MenuModelForSearch> result = new ArrayList<>();
//Stockez 500 pour le déjeuner et 1000 pour le dîner dans le seuil
int threshold = getThreshold(isLunch);
//Stocker tous les menus dans les candidats
List<MenuModelForSearch> candidates = MenuCaches.getSingleton().getMenuList(area, isLunch);
//Vérifiez si la quantité totale du menu acquis dépasse le seuil et ajoutez des menus à partir des candidats au hasard jusqu'à ce qu'il dépasse le seuil.
while (isOverThreshold(threshold, result) == false) {
addElement(result, candidates);
}
//Vérifiez enfin si le menu du déjeuner est inclus. Si le menu du déjeuner est inclus, le résultat sera le menu du déjeuner uniquement.
checkIncludeLunchMenu(result);
return result;
}
Voir Code entier pour chaque méthode.
En ce qui concerne SpringBoot, je me suis référé au site suivant. https://qiita.com/gosutesu/items/961b71a95daf3a2bce96 https://qiita.com/opengl-8080/items/eb3bf3b5301bae398cc2 https://note.com/ymzk_jp/n/n272dc9e5c5d3
Ajoutez des plugins et des bibliothèques à build.gradle afin que gradle puisse utiliser le framework Spring Boot.
La partie où le build.gradle réel de cette époque est commenté en tant que // partie supplémentaire de spring-boot est ajoutée dans ↓.
build.gradle
plugins {
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application
id 'application'
id 'eclipse'
id 'com.diffplug.eclipse.apt' version '3.25.0'
id 'org.springframework.boot' version '2.3.5.RELEASE' //spring-partie post-scriptum de démarrage
id 'io.spring.dependency-management' version '1.0.10.RELEASE'//spring-partie post-scriptum de démarrage
}
version = '2.26.0-SNAPSHOT'
ext.dependentVersion = '2.24.0'
task copyDomaResources(type: Sync) {
from sourceSets.main.resources.srcDirs
into compileJava.destinationDir
include 'doma.compile.config'
include 'META-INF/**/*.sql'
include 'META-INF/**/*.script'
}
compileJava {
dependsOn copyDomaResources
options.encoding = 'UTF-8'
}
compileTestJava {
options.encoding = 'UTF-8'
options.compilerArgs = ['-proc:none']
}
repositories {
mavenCentral()
mavenLocal()
maven {url 'https://oss.sonatype.org/content/repositories/snapshots/'}
}
dependencies {
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.jsoup/jsoup
compile group: 'org.jsoup', name: 'jsoup', version: '1.13.1'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
annotationProcessor "org.seasar.doma:doma:${dependentVersion}"
implementation "org.seasar.doma:doma:${dependentVersion}"
runtimeOnly 'com.h2database:h2:1.3.175'
// https://mvnrepository.com/artifact/org.postgresql/postgresql
compile group: 'org.postgresql', name: 'postgresql', version: '42.2.8'
// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
compile group: 'com.zaxxer', name: 'HikariCP', version: '3.4.1'
// https://mvnrepository.com/artifact/javax.inject/javax.inject
compile group: 'javax.inject', name: 'javax.inject', version: '1'
// https://mvnrepository.com/artifact/io.vavr/vavr
compile group: 'io.vavr', name: 'vavr', version: '0.10.2'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.3.5.RELEASE'//spring-partie post-scriptum de démarrage
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.5.RELEASE'//spring-partie post-scriptum de démarrage
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: '2.3.5.RELEASE'//spring-partie post-scriptum de démarrage
}
//spring-Ajout de la tâche bootJar pour transformer le projet de démarrage en service
bootJar {
launchScript()
}
application {
// Define the main class for the application
mainClassName = 'eternalKurazushi.ServerLuncher'
}
eclipse {
classpath {
file {
whenMerged { classpath ->
classpath.entries.removeAll { it.path == '.apt_generated' }
}
withXml { provider ->
def node = provider.asNode()
// specify output path for .apt_generated
node.appendNode( 'classpathentry', [ kind: 'src', output: 'bin/main', path: '.apt_generated'])
}
}
}
jdt {
javaRuntimeName = 'JavaSE-11'
}
}
ServerLuncher.java
@SpringBootApplication
public class ServerLuncher {
public static void main(String[] args) throws Exception {
SpringApplication.run(ServerLuncher.class, args);
LoadMenu.init();
MenuCaches.getSingleton().load();
}
}
Tout ce que vous avez à faire est d'ajouter l'annotation @SpringBootApplication et d'implémenter SpringApplication.run.
LoadMenu.init();
MenuCaches.getSingleton().load();
Cette partie lit le menu au démarrage du serveur et le stocke dans la base de données, de sorte que le menu dispose également d'une mémoire. En fait, avec cette configuration, je n'ai peut-être pas besoin de DB, mais j'utilise également DB au cas où il serait étendu à l'avenir (probablement pas étendu).
FrontController.java
@Controller
public class FrontController {
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping(value = "/result", method = RequestMethod.POST)
public String getResult(@RequestParam("radio_1") String eatTime, @RequestParam("radio_2") String areaString, Model model) {
if (StringUtils.isEmpty(eatTime) || StringUtils.isEmpty(eatTime)) {
return "error";
}
boolean isLunch = eatTime.equals("le déjeuner") ? true : false;
Areas area = Areas.Japon oriental;
if (areaString.equals("Japon occidental")) {
area = Areas.Japon occidental;
} else if (areaString.equals("Kyushu-Okinawa")) {
area = Areas.Kyushu;
}
List<MenuModelForSearch> gachaResult = Gacha.getResult(area, isLunch);
model.addAttribute("list", gachaResult);
model.addAttribute("sum", getSumString(gachaResult));
model.addAttribute("time", eatTime);
model.addAttribute("area", areaString);
return "result";
}
Implémentez le contrôleur à l'aide de l'annotation @Controller. Spécifiez le chemin correspondant avec l'annotation @RequestMapping. Ceci est similaire à jax-rs. Recevez des valeurs de HTML à l'aide de l'annotation @RequestParam.
model.addAttribute("list", gachaResult);
Vous pouvez transmettre une valeur à html avec addAttribute. Dans cet exemple, la valeur de gachaResult est transmise à html avec la liste des noms de variable.
return "result";
Renvoie le modèle html de / resources / templates / [Valeur de retour du contrôleur] .html. Dans cet exemple, /resources/templates/result.html est lu et renvoyé.
result.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Mugenkura Sushi Gacha</title>
</head>
<body bgcolor=#99FFFF>
<div style="text-align: center">
<main>
<h1>Mugenkura Sushi Gacha</h1>
<p th:text="${time} + ' / ' + ${area}" class="description"></p>
<table border="1" align="center">
<tr>
<th>type</th>
<th>Nom du produit</th>
<th>Prix (hors taxes)</th>
<th>calorie</th>
<!--
<th>Zone de service</th>
<th>À emporter</th>
-->
</tr>
<tr th:each="menu : ${list}">
<td th:text="${menu.type}"></td>
<td th:text="${menu.name}"></td>
<td th:text="${menu.price} + 'Cercle'"></td>
<td th:text="${menu.kcal} + 'kcal'"></td>
<!--
<td th:text="${menu.area}"></td>
<td th:text="${menu.takeout} ? 'Oui' : '不Oui'"></td>
-->
</tr>
</table>
<h3>
<p th:text="${sum}" class="sum"></p>
</h3>
<br>
<form method="POST" action="/result">
<input type="hidden" name="radio_1" th:value="${time}"> <input
type="hidden" name="radio_2" th:value="${area}">
<div style="margin: 2rem 0rem">
<input type="submit" value="Retourner le gacha dans les mêmes conditions"
style="width: 250px; height: 50px">
</div>
</form>
<form method="GET" action="/">
<div style="margin: 2rem 0rem">
<input type="submit" value="Revenir">
</div>
</form>
</main>
</div>
</body>
</html>
th: value = "$ {nom de la variable}" Ensuite, la valeur reçue du contrôleur peut être utilisée. Vous pouvez transmettre une valeur au contrôleur en créant une entrée et en spécifiant un nom à l'aide de la balise form.
Cette fois, j'ai utilisé AWS pour publier une application Web. C'est une application simple, donc je l'ai utilisée
c'est sombre. Recommandé pour les débutants car ce livre est très poli et peut être pratiqué. [Construction du réseau et du serveur à partir de l'édition révisée de base des services Web d'Amazon](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81% 8B% E3% 82% 89% E3% 81% AE% E3% 83% 8D% E3% 83% 83% E3% 83% 88% E3% 83% AF% E3% 83% BC% E3% 82% AF- % E3% 82% B5% E3% 83% BC% E3% 83% 90% E3% 83% BC% E6% A7% 8B% E7% AF% 89 / dp / 4822237443)
Cela fait un moment que je n'ai pas créé quelque chose en dehors du travail. La programmation de travail est amusante, mais la programmation privée est aussi amusante (sélection d'un framework, création d'un environnement, etc.), j'aimerais donc régulièrement améliorer mes compétences.
Si j'ai le temps, j'aimerais travailler sur ce qui suit.