java springboot HTML Produktstruktur

smn000

Neues Mitglied
hallo. ich möchte eine html erstellen, auf der ich eine produktstruktur erstellen kann. dabei möchte ich erstmal Items erstellen , denen ich dann ItemInstances hinzufüge. diese werden unter Item.java in einer Arraylist namens "Uses" gespeichert. jetzt bin ich soweit, dass ich items erstellen kann und im Appstore mit Hilfe einer Id speichern kann. Ich habe auch was geschrieben, dass ich iteminstances den items hinzufügen kann, aber das artet in html immer in eine endlosschleife aus.
mein Appstore:
Java:
@ApplicationScope
@Component
public class AppStore {

    inginf.SampleStore sampleStore = new inginf.SampleStore();

    private java.util.ArrayList<inginf.Item> itemStore
        = new java.util.ArrayList<inginf.Item>();
    
    public AppStore() {
        itemStore = sampleStore.getItems();
    }

    public ArrayList<inginf.Item> getItemStore() {
        return itemStore;
    }       
    public int getItemCount() {
        return itemStore.size();
    }
    public inginf.Item addNewItem(inginf.Item item) {
        if (itemStore.size() == 0)
            item.Id = 1;
        else
            item.Id = itemStore.get(itemStore.size()-1).Id + 1;
        itemStore.add(item);
        return item;
    }
der controller, wobei ich das letzte postmapping nicht weiß,ob es richtig ist. der rest müsse passen
Code:
@Controller
public class ItemController {

    @Autowired
    private ApplicationContext context;
    AppStore _AppStore;
    AppStore getAppStore() {
        if (_AppStore == null)
            _AppStore = context.getBean(AppStore.class);
        return _AppStore;
    }

    @PostMapping("/items-gui")
    public String createItem(
        Model model,
        HttpSession session,
        @RequestParam Map<String, String> body )
    {       
        inginf.Item item = new inginf.Item(
            body.get("Nomenclature"),
            body.get("Description"),
            body.get("Material"));
       
        getAppStore().addNewItem(item);
        model.addAttribute(
                "id", item.Id);
        return "itemCreated";
    }

    @GetMapping("/items-gui")
    public String createItemDialog() {
        return "itemTemplate";
    }
    
    @GetMapping("/items-gui/list")
    public String listItems(Model model) {
        model.addAttribute(
            "items",
            getAppStore().getItemStore());
        return "listItems";
    }

    @GetMapping("/items-gui/{id}/delete")
    public String deleteItem(@PathVariable int id, Model model) {       
        model.addAttribute(
            "id", id);
        for (Item item : getAppStore().getItemStore())
            if (item.Id == id) {
                getAppStore().getItemStore().remove(item);
                break;
            }
        return "itemDeleted";
    }

    @GetMapping("/items-gui/{id}/show")
    public String showItem(@PathVariable int id, Model model) {       
        model.addAttribute(
            "id", id);
        for (Item item : getAppStore().getItemStore())
            if (item.Id == id) {
                model.addAttribute(
                    "item", item);
                    model.addAttribute(
                        "iteminstances", item.getUses());
                break;
            }
        return "showItem";
    }
  

    @PostMapping("/items-gui/{id}/add-iteminstances")
    public String addItemInstances(
        @PathVariable int id,
        Model model,
        HttpSession session,
        @RequestParam Map<String, String> body )
    {       
        model.addAttribute(
            "id", id);
        for (Item item : getAppStore().getItemStore())
        
            if (item.getId() == id) {
                ItemInstance itemInstance = new ItemInstance(body.get("Name"), item);
           item.getUses().add(itemInstance);
          
            }
        

            return "redirect:/items-gui/{id}/show";
}

}

und das ist das html für die ausgabe der struktur.

HTML:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Create Item</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>
<body>
<h2>Show Item</h2>

<table>
    <tr>
        <td>Item Name</td>
        <td th:text="${item.nomenclature}">Item Name</td>
    </tr>
    <tr>
        <td>Item Description</td>
        <td th:text="${item.description}">Item Description</td>
    </tr>
    <tr>
        <td>Item Material</td>
        <td th:text="${item.material}">Item Material</td>
    </tr>
</table>
<form th:action="@{/items-gui/{id}/add-iteminstances(id=${item.id})}" method="post">
    <label for="Name">Name</label>
    <input type="text" id="Name" name="Name" required/>
    <button type="submit">Hinzufügen</button>
</form>

<form th:action="@{/items-gui/{id}/add-iteminstances(id=${item.id})}" method="post">
    <label for="Name">Name</label>
    <input type="text" id="Name" name="Name" required/>
    <button type="submit">Hinzufügen</button>
</form>

<!-- Formular zum Löschen einer vorhandenen ItemInstance -->
<form th:action="@{/items-gui/{id}/delete-iteminstances(id=${item.id})}" method="post">
    <label for="InstanceId">ItemInstance ID to delete</label>
    <input type="text" id="InstanceId" name="InstanceId" required/>
    <button type="submit">Löschen</button>
</form>



<h3>Produktstruktur:</h3>
<div class="tree">
    <div th:fragment="treeviewItem(item)">
        <span th:text="${item.nomenclature}">Item</span>
        <ul th:if="${item.getUses().size() > 0}">           
            <li th:each="child : ${item.getUses()}">
                <i><span th:text="${child.name}">ItemInstance</span></i>                               
                
                <div th:replace="this :: treeviewItem(${child.represents})"></div>
            </li>
        </ul>
    </div>
</div>


</body>
</html>

daneben habe ich noch ne item klasse , in der die "Arraylist<iteminstances> Uses" drinnen ist, eine iteminstances klasse mit " String name;" und "Item represents; "
zusätzlich auch noch einige andere templates und einen restcontroller, die aber weniger relevant für das problem sind.

ich weiß nicht genau wie ich jetzt eine verbindung von item zu iteminstance machen soll. ich hab das postmapping im controller geschrieben, aber das artet in eine endlosschleife aus . kann mir wer einen tipp geben?
 
Also Dein Code ist grausig ...

1) Zu dem Code ist Dir doch schon einmal gesagt worden, dass Du da einfach direkt injecten solltest. Also aus
Java:
    @Autowired
    private ApplicationContext context;
    AppStore _AppStore;
    AppStore getAppStore() {
        if (_AppStore == null)
            _AppStore = context.getBean(AppStore.class);
        return _AppStore;
    }
machst Du einfach:
Code:
    @Autowired
    private AppStore appStore;
und nutzt den dann einfach.

2) Der Code ist an der falschen Stelle und du machst keinen Block, obwohl mehrere Zeilen kommen?
Java:
        for (Item item : getAppStore().getItemStore())
            if (item.Id == id) {
                getAppStore().getItemStore().remove(item);
                break;
            }
Also zum einen gehört das nicht den den Controller sondern in das Repository (Also deinen AppStore) und zum anderen solltest Du der for Schleife auch { } gönnen. Das vermeidet Fehler und ist dann deutlich besser lesbar.
Also fachliche Logik gehört zum Model und damit gehört es nicht zum Controller. Der Controller ist nur sowas wie ein Bindeglied zwischen View und Model. Du rufst also Methoden auf dem Repository oder einem Service auf!

3) Wie bei 2) ist das fast komplett Code, der ins Repository gehört:
Java:
        for (Item item : getAppStore().getItemStore())
            if (item.Id == id) {
                model.addAttribute(
                    "item", item);
                    model.addAttribute(
                        "iteminstances", item.getUses());
                break;
            }
Du hast also ein Item item = appStore.getItemById(id); und dann die model.addAttribute Aufrufe.

Und zu Deinem eigentlichen Problem: Kannst Du evtl. einmal genauer Beschreiben, was Dein Problem ist? Wo kommt es zu einer Endlosschleife? Das klingt doch vom Ansatz her wie eine einfache 1:n Beziehung, die Du hier darstellen willst. Und dazu gibt es doch genügend Beispiele. Was genau willst Du denn überhaupt haben? Im Augenblick bin ich auch etwas unsicher, was Du überhaupt im HTML bezweckst. Der Aufbau sieht auf jeden Fall alles andere als vernünftig aus, und bei dem läuft es mir etwas kalt dem Rücken runter:
Java:
    @PostMapping("/items-gui/{id}/add-iteminstances")
    public String addItemInstances(
        @PathVariable int id,
        Model model,
        HttpSession session,
        @RequestParam Map<String, String> body )
    {       
        model.addAttribute(
            "id", id);
        for (Item item : getAppStore().getItemStore())
        
            if (item.getId() == id) {
                ItemInstance itemInstance = new ItemInstance(body.get("Name"), item);
           item.getUses().add(itemInstance);
          
            }
        

            return "redirect:/items-gui/{id}/show";
}

Schau Dir doch einmal paar Beispiele an, wie Du Formulardaten besser bearbeiten kannst als so auf das Name Feld zuzugreifen.
In der Regel machst Du so Datentransfers einfach per DTO Klassen und dann bekommst Du in der Controller Methode direkt die DTO Instanz.
Auf die Schnelle mal geschaut - evtl. hilft Spring Boot CRUD Application with Thymeleaf | Baeldung etwas.
 

Zurück
Oben