Przekazanie listy z widoku do kontrolera - spring mvc

0

Witajcie.

Mam problem z przekazaniem zaznaczonych checkboxem pozycji do kontrolera.
Fragment klasy konrolera

 
	@RequestMapping(value = "/addmedicaments/{id}")
	public ModelAndView addMedicaments(@PathVariable int id, Principal principal)
	{
		ModelAndView mav = new ModelAndView("diseaseAddMedicaments");
		String name = principal.getName();
		User user = userService.findByName(name);
		mav.addObject("medicaments", medicamentService.findByUser(user));
		return mav;
		
	}
	
	@RequestMapping(value = "/aaddmedicaments/do")
	public ModelAndView addMedicamentsSubmit(List<Medicament> medicaments, Principal principal)
	{
		ModelAndView mav = new ModelAndView("redirect:/disease/list.html");


		
		
		return mav;

oraz jsp

				<form:form method="POST" modelAttribute="medicaments" action="do.html">
						<table id="myTable">
							<thead>
								<tr>
									<td>dodaj</td>
									<td>nazwa leku</td>
									<td>opakowanie</td>
									<td>data waznosci</td>
								</tr>
							</thead>
							<tbody>
								<c:forEach items="${medicaments}" var="medicament">
									<tr>
										<td><form:checkbox path="medicaments" value="${medicament}"/></td>
										<td>${medicament.medicamentDb.name}</td>
										<td>${medicament.medicamentDb.pack}</td>
										<td>${medicament.dateExpiration}</td>
									</tr>
								</c:forEach>
							</tbody>
						</table>
					<input type="submit" value="Dodaji"/>
				</form:form>
			</div>

Dostaje błąd przy próbie wyświetlenia strony.
Invalid property 'medicaments' of bean class [java.util.ArrayList]: Bean property 'medicaments' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

Nie mam pojęcia jak przekazać z powrotem listę obiektów, które przekazałem do widoku.

Czy ktoś ma pomysł jak to zrobić?

Generalnie uczę się programować od jakiegoś czasu więc z góry przepraszam za błędy merytoryczne, językowe, kodowe, w nazewnictwie, itp.

0

Musisz tą listę dodać do modelu a ty stworzyłeś nowy new ModelAndView("redirect:/disease/list.html"); i tyle.
Popatrz np. tutaj: https://github.com/Pharisaeus/SpringScaffoldApplication/blob/master/src/main/java/scaffold/controllers/main/MainController.java
Zresztą przecież nawet w tym swoim kodzie dodajesz obiekty do modelu, więc nie bardzo rozumiem czemu raz wiedziałeś jak to zrobić a drugi raz nie...

0

Dzięki za odpowiedź.
Odpowiadając na Twoje pytanie to wynika to z mojej niewiedzy, braku doświadczenia i pewnie jeszcze wielu innych czynników :)
Wracając do tematu wydaje mi się że problem leży w

<form:checkbox path="medicaments" value="${medicament}"/>

bo bez tego przynajmniej strona się wyświetla.

Zmieniłem tak jak pisałeś - a przynajmniej wydaje mi się:

	@RequestMapping(value = "/addmedicaments/17")
	public ModelAndView addMedicaments(Principal principal)
	{
		ModelAndView mav = new ModelAndView("diseaseAddMedicaments");
		String name = principal.getName();
		User user = userService.findByName(name);
		mav.addObject("medicaments", medicamentService.findByUser(user));
		return mav;
		
	}
	
	@RequestMapping(value = "/addmedicaments/do")
	public ModelAndView addMedicamentsSubmit(List<Medicament> medicaments, Principal principal)
	{
		System.out.println(medicaments);
		ModelAndView mav = addMedicaments(principal);
		

		
		
		return mav;
	}

ale przy submiecie rzuca błędem:
Failed to instantiate [java.util.List]: Specified class is an interface

W metodzie z GET addMedicaments dałem statyczną wartość, żeby na razie nie przekazywać id z metody addMedicamentsSubmit

Ahh. Głupieję już od tego... Pewnie wypisałem programistyczne bzdury i zaraz zostanę zjedzony.

0

o_O ale teraz to w ogóle nie wiem co ten kod ma wspólnego z tym co opisywałeś. Ty chcesz odebrać z widoku listę obiektów z formularza czy chcesz WYSŁAĆ do widoku taka liste?

0

Odebrać. Źle zrozumiałem Twoją pierwszą odpowiedź "Musisz tą listę dodać do modelu". Mógłbyś mi to wytłumaczyć?
Metoda addMedicaments działa wg mnie dobrze - wrzuca do widoku dane - nie trzeba jej zmieniać. Natomiast druga metoda addMedicamentsSubmit które "odbiera" dane z formularza jest błędna. Jako parametry przyjmuje listę obiektów i użytkownika (to można pominąć). W metodzie przetwarzam sobie tę listę i nie mogłem zwrócić nowego widoku ModelAndView mav = new ModelAndView("redirect:/disease/list.html"); ?

0

Nadal mam problem...
Dodałem klasę z listą

public class MedicamentForm {
	
	private List<Medicament> medicaments;
}
//gettery i settery

zmieniłem kontrolery

	@RequestMapping(value = "/addmedicaments/{id}")
	public ModelAndView addMedicaments(@PathVariable int id, Principal principal)
	{
		ModelAndView mav = new ModelAndView("diseaseAddMedicaments");
		String name = principal.getName();
		User user = userService.findByName(name);
		MedicamentForm medicamentForm = new MedicamentForm();
		List<Medicament> list = medicamentService.findByUser(user);
		System.out.println(list);
		medicamentForm.setMedicaments(list);
		mav.addObject("medicamentForm", medicamentForm);
		return mav;
		
	}
	
	@RequestMapping(value = "/addmedicaments/do")
	public ModelAndView addMedicamentsSubmit(@ModelAttribute("medicamentForm") MedicamentForm medicamentForm, Principal principal)
	{
		
		List<Medicament> medicaments = medicamentForm.getMedicaments();
		ModelAndView mav = new ModelAndView("redirect:/disease/list.html");
		return mav;
	}

oraz jsp

<form:form method="POST" modelAttribute="medicamentForm" action="do.html">
						<table id="myTable">
							<thead>
								<tr>
									<td>dodaj</td>
									<td>nazwa leku</td>
									<td>opakowanie</td>
									<td>data waznosci</td>
								</tr>
							</thead>
							<tbody>
								<c:forEach items="${medicamentForm.medicaments}" var="medicament" varStatus="status">
									<tr>
										<td><form:checkbox path="medicaments[${status.index}]" value="${medicament}"/></td>
										<td>${medicament.medicamentDb.name}</td>
										<td>${medicament.medicamentDb.pack}</td>
										<td>${medicament.dateExpiration}</td>
									</tr>
								</c:forEach>
							</tbody>
						</table>
					<input type="submit" value="Dodaj"/>
				</form:form>

Lista się wyświetla. Jak żaden checkbox nie jest zaznaczony to metoda addMedicamentsSubmit wykonuje się. Jak zaznacze cokolwiek to dostaję

HTTP ERROR 400

Problem accessing /disease/addmedicaments/do.html. Reason:

    Bad Request

Checkboxy w podglądzie strony wyglądają tak:

<td><input id="medicaments01" name="medicaments[0]" type="checkbox" value="pl.tomo.entity.Medicament@1face4c0" checked="checked"/><input type="hidden" name="_medicaments[0]" value="on"/>
0

To co zrobiłeś nie ma sensu bo checkbox jest albo checked albo nie. A ty mu próbujesz pchać jakąś dziwną wartość...

0

To skąd submit będzie wiedział wiedział co pchać do listy i w jaki sposób to zrobi? Myślałem, że w path daje listę a w value wartość do wrzucenia do niej...

edit:
Już rozumiem.
Dodałem listę do MedicamentForm: private List<Integer> ids;

a w jsp zmieniłem form:checkbox
na

<c:forEach items="${medicamentForm.medicaments}" var="medicament" varStatus="status">
									<tr>
										<td><form:checkbox path="ids" value="${medicament.id}"/></td>
										<td>${medicament.medicamentDb.name}</td>
										<td>${medicament.medicamentDb.pack}</td>
										<td>${medicament.dateExpiration}</td>
									</tr>
								</c:forEach>

gdzie do listy wrzucam id zaznaczonych pozycji i działa! :)

Tylko zastanawia mnie czemu nie mogłem wrzucić obiektów innych niż Integer, tj Medicament do listy medicaments z klasy MedicamentForm.

form dla Integer

<td><form:checkbox path="ids" value="${medicament.id}"/></td>

form dla Medicament

<td><form:checkbox path="medicaments" value="${medicament}"/></td>

Przy tym drugim wychodzi bad request...

1 użytkowników online, w tym zalogowanych: 0, gości: 1