在Spring 5中传递绑定的对象列表时出现问题。

huangapple go评论78阅读模式
英文:

Problem while passing binded list of objects in Spring 5

问题

早上好,
我正在开发一个系统,可以同时接受多个对象,使用的技术包括:

  • 后端使用 Spring 5.2.5.RELEASE,
  • 前端使用 JSP。

主要目标是让用户通过一个表单一次性输入 16 条“Delta P”数据记录(预定义数量,因此数组长度不是动态的)。
由于所有记录中的“nome_operatore”和“data_operazione_delta_p”都是相等的,它们只提交一次,然后在控制器中复制到所有提交的记录中。

到目前为止,我根据这里的各种教程和网上的教程创建了后续的类。
总的来说,视图显示正确(我扫描了Spring生成的代码,就我所知,它是正确的),并且用于显示表单页面的GetMapping也正常工作(我进行了调试,以查看是否有一些数据不正确,但我没有找到错误)。
唯一的问题是,当我提交表单时,页面会冻结一段时间,然后Chrome显示一个提示,说无法加载页面。
服务器仍在运行,因为服务器继续正确记录,但是以下这一行

logger.info("submitted form to create multiple Delta P data");

从未达到。
Chrome控制台中也没有显示任何错误。

如果这不是一次上传多个项目的正确方法,那么在Spring 5中应该如何实现?

编辑

经过调查,我发现Chrome显示了RESULT_CODE_HUNG错误,但是在网络上,我找不到有用的东西来修复它,只有人们在抱怨“Chrome关闭页面”,有人能解释一下这个错误至少是什么意思吗?我尝试自己了解,但没有成功。Edge 和 Firefox 也显示相同的错误。

列表包装器

package com.entsorgafin.dto;

import com.entsorgafin.model.Dato_delta_p;

import java.util.ArrayList;
import java.util.List;

public class DeltaPListWrapper {
    private List<Dato_delta_p> deltaPList;

    public DeltaPListWrapper() {
        this.deltaPList = new ArrayList<>();
    }

    public List<Dato_delta_p> getDeltaPList() {
        return deltaPList;
    }

    public void setDeltaPList(List<Dato_delta_p> deltaPList) {
        this.deltaPList = deltaPList;
    }

    public void add(Dato_delta_p dato_delta_p) {
        this.deltaPList.add(dato_delta_p);
    }
}

控制器方法

/**
 * Shows the form to insert a new delta p data series in the system.
 * <p>
 * Returns the form page.
 *
 * @param model ModelMap of the UI
 * @return The form page to insert one record for each sector
 */
@GetMapping("/addDeltaP")
public String addDeltaP(ModelMap model) {
    logger.info("adding Delta P data");

    logger.debug("finding infos for front end representation");
    //finding users to relate the records with
    List<Utente> users = utentiService.findAllUsers();
    logger.debug("found " + users.size() + " users");
    Map<Integer, String> userForFE = new HashMap<>();
    for(Utente utente : users) {
        userForFE.put(utente.getId_utente(), utente.getNome() + " " + utente.getCognome());
    }
    model.addAttribute("users", userForFE);

    //finding active sectors
    List<Settore> activeSectors = new ArrayList<>();
    activeSectors.addAll(settoriService.findActiveSectorForPhase("act"));
    activeSectors.addAll(settoriService.findActiveSectorForPhase("cur"));
    logger.debug("found " + activeSectors.size() + " active sectors");

    //creating wrapper which contains multiple Delta P records
    DeltaPListWrapper listWrapper = new DeltaPListWrapper();

    //Pre-filling sector field for delta P data
    for(Settore sect : activeSectors) {
        Dato_delta_p dato_delta_p = new Dato_delta_p();
        dato_delta_p.setSettore(sect);
        listWrapper.add(dato_delta_p);
    }
    model.addAttribute("deltaPData", listWrapper);
    model.addAttribute("activeSectorNumber", activeSectors.size());

    return "uploadDeltaPData";
}

/**
 * Saves a new series of data record in the database.
 *
 * @param listWrapper List of Delta p data to create
 * @return Returns the homepage
 */
@PostMapping("/addDeltaP")
public String addDeltaP(@ModelAttribute("deltaPData") DeltaPListWrapper listWrapper) {
    logger.info("submitted form to create multiple Delta P data");

    /*
    getting Date of the first record, operations are performed on the same date, so
    every record will have the same property for data_operazione

    The same stands for the user who performed the operations
     */
    LocalDate dataOperazione = listWrapper.getDeltaPList().get(0).getData_operazione_delta_p();
    Utente idUtente = listWrapper.getDeltaPList().get(0).getUtente_id_utente();

    /*
    Filling delta P data with active batch for the sector they are from
     */
    for(Dato_delta_p dato_delta_p : listWrapper.getDeltaPList()) {
        dato_delta_p.setUtente_id_utente(idUtente);
        dato_delta_p.setData_operazione_delta_p(dataOperazione);

        String phase;
        Settore used = settoriService.findSectorById(dato_delta_p.getSettore().getId_settore());
        if(used.getFase().equals("act")) {
            phase = "act";
        } else {
            phase = "cur";
        }

        Lotto referencedLotto = lottoService
                .findActiveBatchInSectorAndDate(dato_delta_p.getData_operazione_delta_p(), dato_delta_p
                        .getSettore(), phase);
        logger.debug("found Lotto with ID " + referencedLotto.getId_lotto() + " for Delta P record");
        dato_delta_p.setLotto_id_lotto(referencedLotto);

        //creating the data
        dati_delta_pService.createDeltaPData(dato_delta_p);
        logger.info("Delta P data created correctly");
    }

    return "redirect:/entsorgafin/home";
}

JSP 视图

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<jsp:include page="header.jsp"/>
<div class="
<details>
<summary>英文:</summary>
Good Morning,
I am developing a system which can accept multiple object at the same time, technology used are:
- Spring 5.2.5.RELEASE For the backend,
- Jsp for Front layer.
The main goal is to let the user put 16 (predefined number, so it is not dynamic the lenght of the array) records of a &quot;Delta P&quot; data with only one form.
As the &quot;nome_operatore&quot; and &quot;data_operazione_delta_p&quot; are equal in all the records, they are submitted only ones and then replicated in the controller for all records submitted.
Since now I came out with the subsequent classes following various tutorials here on SO and over the net. 
In general, the view is correctly displayed (I scanned the code generated by Spring and it is correct as far as I know) and the `GetMapping` to display the form page works correctly as well (I debugged to see if some data were not correct, but I found no errors).
The only problem is that when I submit the form, the page freezes and after a while Chrome display an advise saying that is impossibile to load the page.
The server is still running, as the server keeps logging correctly, but the line 
logger.info(&quot;submitted form to create multiple Delta P data&quot;);
is never reached.
No errors are displayed either in Chrome console.
If this is not the correct way to upload multiple items at one time, how this could be done in Spring 5?
**EDIT**
After investigation I found chrome giving a `RESULT_CODE_HUNG` error, but on the net I found nothing useful to fix it, only people complaining about &quot;chrome killing pages&quot;, can someone explain what this error means at least? I tried to document myself but with no success. The same error shows up also in Edge and Firefox.
**List wrapper**
package com.entsorgafin.dto;
import com.entsorgafin.model.Dato_delta_p;
import java.util.ArrayList;
import java.util.List;
public class DeltaPListWrapper
{
private List&lt;Dato_delta_p&gt; deltaPList;
public DeltaPListWrapper()
{
this.deltaPList = new ArrayList&lt;&gt;();
}
public List&lt;Dato_delta_p&gt; getDeltaPList()
{
return deltaPList;
}
public void setDeltaPList(List&lt;Dato_delta_p&gt; deltaPList)
{
this.deltaPList = deltaPList;
}
public void add(Dato_delta_p dato_delta_p)
{
this.deltaPList.add(dato_delta_p);
}
}
**Controller methods**
/**
* Shows the form to insert a new delta p data series in the system.
* &lt;p&gt;
* Returns the form page.
*
* @param model ModelMap of the UI
* @return The form page to insert one record for each sector
*/
@GetMapping(&quot;/addDeltaP&quot;)
public String addDeltaP(ModelMap model)
{
logger.info(&quot;adding Delta P data&quot;);
logger.debug(&quot;finding infos for front end representation&quot;);
//finding users to relate the records with
List&lt;Utente&gt; users = utentiService.findAllUsers();
logger.debug(&quot;found &quot; + users.size() + &quot; users&quot;);
Map&lt;Integer, String&gt; userForFE = new HashMap&lt;&gt;();
for(Utente utente : users)
{
userForFE.put(utente.getId_utente(), utente.getNome() + &quot; &quot; + utente.getCognome());
}
model.addAttribute(&quot;users&quot;, userForFE);
//finding active sectors
List&lt;Settore&gt; activeSectors = new ArrayList&lt;&gt;();
activeSectors.addAll(settoriService.findActiveSectorForPhase(&quot;act&quot;));
activeSectors.addAll(settoriService.findActiveSectorForPhase(&quot;cur&quot;));
logger.debug(&quot;found &quot; + activeSectors.size() + &quot; active sectors&quot;);
//creating wrapper which contains multiple Delta P records
DeltaPListWrapper listWrapper = new DeltaPListWrapper();
//Pre-filling sector field for delta P data
for(Settore sect : activeSectors)
{
Dato_delta_p dato_delta_p = new Dato_delta_p();
dato_delta_p.setSettore(sect);
listWrapper.add(dato_delta_p);
}
model.addAttribute(&quot;deltaPData&quot;, listWrapper);
model.addAttribute(&quot;activeSectorNumber&quot;, activeSectors.size());
return &quot;uploadDeltaPData&quot;;
}
/**
* Saves a new series of data record in the database.
*
* @param listWrapper List of Delta p data to create
* @return Returns the homepage
*/
@PostMapping(&quot;/addDeltaP&quot;)
public String addDeltaP(@ModelAttribute(&quot;deltaPData&quot;) DeltaPListWrapper listWrapper)
{
logger.info(&quot;submitted form to create multiple Delta P data&quot;);
/*
getting Date of the first record, operations are performed on the same date, so
every record will have the same property for data_operazione
The same stands for the user who performed the operations
*/
LocalDate dataOperazione = listWrapper.getDeltaPList().get(0).getData_operazione_delta_p();
Utente idUtente = listWrapper.getDeltaPList().get(0).getUtente_id_utente();
/*
Filling delta P data with active batch for the sector they are from
*/
for(Dato_delta_p dato_delta_p : listWrapper.getDeltaPList())
{
dato_delta_p.setUtente_id_utente(idUtente);
dato_delta_p.setData_operazione_delta_p(dataOperazione);
String phase;
Settore used = settoriService.findSectorById(dato_delta_p.getSettore().getId_settore());
if(used.getFase().equals(&quot;act&quot;))
{
phase = &quot;act&quot;;
} else
{
phase = &quot;cur&quot;;
}
Lotto referencedLotto = lottoService
.findActiveBatchInSectorAndDate(dato_delta_p.getData_operazione_delta_p(), dato_delta_p
.getSettore(), phase);
logger.debug(&quot;found Lotto with ID &quot; + referencedLotto.getId_lotto() + &quot; for Delta P record&quot;);
dato_delta_p.setLotto_id_lotto(referencedLotto);
//creating the data
dati_delta_pService.createDeltaPData(dato_delta_p);
logger.info(&quot;Delta P data created correctly&quot;);
}
return &quot;redirect:/entsorgafin/home&quot;;
}
**JSP view**
&lt;%@ page contentType=&quot;text/html;charset=UTF-8&quot; language=&quot;java&quot; %&gt;
&lt;%@ taglib prefix=&quot;c&quot; uri=&quot;http://java.sun.com/jsp/jstl/core&quot; %&gt;
&lt;%@ taglib prefix=&quot;form&quot; uri=&quot;http://www.springframework.org/tags/form&quot; %&gt;
&lt;jsp:include page=&quot;header.jsp&quot;/&gt;
&lt;div class=&quot;container&quot;&gt;
&lt;h1&gt;Inserisci i dati delta P&lt;/h1&gt;
&lt;form:form method=&quot;post&quot; modelAttribute=&quot;deltaPData&quot; onsubmit=&quot;enableFields(${activeSectorNumber})&quot;&gt;
&lt;div class=&quot;row&quot;&gt;
&lt;div class=&quot;form-group col&quot;&gt;
&lt;label for=&quot;utente_id_utente&quot;&gt;Nome dell&#39;operatore&lt;/label&gt;
&lt;form:select class=&quot;form-control&quot; id=&quot;utente_id_utente&quot; path=&quot;${deltaPList[0].utente_id_utente.id_utente}&quot; required=&quot;required&quot;&gt;
&lt;form:option value=&quot;&quot; /&gt;
&lt;form:options items=&quot;${users}&quot; /&gt;
&lt;/form:select&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group col&quot;&gt;
&lt;label for=&quot;data_operazione_delta_p&quot;&gt;Data dell&#39;operazione&lt;/label&gt;
&lt;form:input path=&quot;${deltaPList[0].data_operazione_delta_p}&quot; type=&quot;date&quot; class=&quot;form-control&quot; id=&quot;data_operazione_delta_p&quot; required=&quot;required&quot; /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;row text-center&quot;&gt;
&lt;div class=&quot;col my-auto&quot;&gt;Numero del settore&lt;/div&gt;
&lt;div class=&quot;col my-auto&quot;&gt;Valore deltaP rilevato&lt;/div&gt;
&lt;div class=&quot;col my-auto&quot;&gt;Velocit&#224; ventilatore&lt;/div&gt;
&lt;div class=&quot;col my-auto&quot;&gt;Settore pieno&lt;/div&gt;
&lt;div class=&quot;col my-auto&quot;&gt;Settore in caricamento&lt;/div&gt;
&lt;/div&gt;
&lt;c:forEach items=&quot;${deltaPData.deltaPList}&quot; varStatus=&quot;i&quot;&gt;
&lt;form:input path=&quot;deltaPList[${i.index}].id_dato_delta_p&quot; type=&quot;hidden&quot; id=&quot;id_dati_delta_p&quot; /&gt;
&lt;div class=&quot;row text-center&quot;&gt;
&lt;div class=&quot;form-group col&quot;&gt;
&lt;form:input path=&quot;deltaPList[${i.index}].settore.id_settore&quot; class=&quot;form-control text-center&quot; id=&quot;settore${i.index}&quot; required=&quot;required&quot; disabled=&quot;true&quot;/&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group col&quot;&gt;
&lt;form:input path=&quot;deltaPList[${i.index}].valore_delta_p&quot; type=&quot;number&quot; step=&quot;0.01&quot; class=&quot;form-control&quot; id=&quot;valore_delta_p&quot; required=&quot;required&quot; /&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group col&quot;&gt;
&lt;form:input path=&quot;deltaPList[${i.index}].velocita_ventilatore&quot; type=&quot;number&quot; step=&quot;0.01&quot; class=&quot;form-control&quot; id=&quot;velocita_ventilatore&quot; required=&quot;required&quot; /&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group col my-auto&quot;&gt;
&lt;form:checkbox path=&quot;deltaPList[${i.index}].stato_settore_pieno&quot; id=&quot;stato_settore_pieno${i.index}&quot; value=&quot;true&quot; onclick=&quot;disableSettoreCaricoBox(${i.index})&quot;/&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group col my-auto&quot;&gt;
&lt;form:checkbox path=&quot;deltaPList[${i.index}].stato_settore_carico&quot; id=&quot;stato_settore_carico${i.index}&quot; value=&quot;true&quot; onclick=&quot;disableSettorePienoBox(${i.index})&quot;/&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/c:forEach&gt;
&lt;input type=&quot;submit&quot; value=&quot;create&quot; class=&quot;btn btn-primary btn-sm&quot;&gt;
&lt;/form:form&gt;
&lt;/div&gt;
&lt;jsp:include page=&quot;footer.jsp&quot;/&gt;
&lt;script&gt;
function disableSettoreCaricoBox(i)
{
const checked = document.getElementById(&#39;stato_settore_pieno&#39; + i).checked;
document.getElementById(&quot;stato_settore_carico&quot; + i).disabled = !!checked;
}
function disableSettorePienoBox(i)
{
const checked = document.getElementById(&#39;stato_settore_carico&#39; + i).checked;
document.getElementById(&quot;stato_settore_pieno&quot; + i).disabled = !!checked;
}
function enableFields(i)
{
for(let x = 0; x &lt; i; x++)
{
document.getElementById(&quot;settore&quot; + x).disabled = false;
}
}
&lt;/script&gt;
</details>
# 答案1
**得分**: 0
我实际上感到有点傻,之前没有注意到它,在关注Spring可能的错误之后,我错过了代码中实际错误的一个细小点:JavaScript函数。
```javascript
function enableFields(i)
{
for(let x = 0; x < i; i++)
{
document.getElementById("settore" + x).disabled = false;
}
}

应该是

function enableFields(i)
{
    for(let x = 0; x < i; x++)
    {
        document.getElementById("settore" + x).disabled = false;
    }
}

我会更正代码,希望这对正在寻找Spring 5中多行提交示例的人有所帮助。

英文:

I actually feel kind of an idiot for not noticing it before, after focusing on Spring possible errors I lost a minor point in the code where the error actually is: Javascript function.

function enableFields(i)
{
for(let x = 0; x &lt; i; i++)
{
document.getElementById(&quot;settore&quot; + x).disabled = false;
}
}

should be

function enableFields(i)
{
for(let x = 0; x &lt; i; x++)
{
document.getElementById(&quot;settore&quot; + x).disabled = false;
}
}

I'll correct the quetion code, hope this could anyway help someone who's searching an example of multi row submitting in Spring 5.

huangapple
  • 本文由 发表于 2020年7月21日 18:23:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63012450.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定