Unable to bind checkboxes even after registering custom property editor - spring

I've the following sequence of steps to register a team:
Select Team - This will display the list of players of this team as check boxes (JSP page below)
User can select one or more players displayed
newdTeam request handler method should be called setting the selected players from step 2 above. The handler is being called but the players set is empty even if I've selected players in step 2. Not sure where the issue is.
I doesn't see the property editor invoked. Any help is appreciated.
Team
#NodeEntity
public class Team
{
#GraphId
private Long nodeId;
#GraphProperty
#Indexed (unique = true)
private String name;
#Fetch
#RelatedTo (type = "PLAYED_WITH_TEAM", direction = Direction.INCOMING)
private final Set<Player> players = new HashSet<Player>();
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = StringUtil.capitalizeFirstLetter(name);
}
public Long getNodeId()
{
return nodeId;
}
public Collection<Player> getPlayers()
{
return players;
}
public void setPlayers(Set<Player> plyrs)
{
System.err.println("called set plrs");
players.addAll(plyrs);
}
}
Player
#NodeEntity
public class Player
{
#GraphId
private Long nodeId;
#Indexed (unique = true)
private String name;
#GraphProperty
#Indexed
private String firstName;
#GraphProperty
private String email;
//getters and setters
}
Controller
#Controller
#RequestMapping ("/registration")
public class RegistrationController
{
private transient final Logger LOG = LoggerFactory.getLogger(getClass());
#Autowired
private LeagueRepository leagueRepo;
#Autowired
private TeamRepository teamRepo;
#RequestMapping (method = RequestMethod.GET)
public String get()
{
return "/registration/start";
}
#Transactional
#RequestMapping (value = "/start", method = RequestMethod.POST)
public String hasParticipatedEarlier(#RequestParam boolean participatedInEarlierLeague, Model model)
{
if (participatedInEarlierLeague)
{
LOG.debug("Participated in earlier leagues. Retrieving the past league teams.");
Iterable<League> allLeagues = leagueRepo.findAll();
Set<League> sortedLeagues = new TreeSet<League>();
for (League l: allLeagues)
{
sortedLeagues.add(l);
}
LOG.debug("Past leagues sorted by start date {}", sortedLeagues);
model.addAttribute("pastLeagues", sortedLeagues);
}
else
{
LOG.debug("Did not participate in earlier leagues. Redirecting to register the new one.");
}
return "/registration/leagues";
}
#RequestMapping (value = "/selectTeam", method = RequestMethod.POST)
public String selectTeam(#RequestParam Long selectedTeam, Model model)
{
LOG.debug("Participated as team {} in previous league", selectedTeam);
Team team = teamRepo.findOne(selectedTeam);
model.addAttribute("team", team);
model.addAttribute("players", team.getPlayers());
return "registration/players";
}
#RequestMapping (value = "/newTeam", method = RequestMethod.POST)
public String newdTeam(#ModelAttribute Team team, Model model)
{
LOG.debug("Selected players from existing list {}", team.getPlayers());
return "registration/registrationConfirmation";
}
#InitBinder
public void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(Player.class, new PlayerPropertyEditor());
}
}
PlayerPropertyEditor
public class PlayerPropertyEditor extends PropertyEditorSupport
{
#Autowired
PlayerRepository playerRepo;
#Override
public String getAsText()
{
System.err.println("get as txt");
return ((Player) getValue()).getNodeId().toString();
}
#Override
public void setAsText(String incomingId) throws IllegalArgumentException
{
System.err.println(incomingId);
Player player = playerRepo.findOne(Long.valueOf(incomingId));
setValue(player);
}
}
JSP
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%# taglib prefix="f" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Players of ${team.name}</title>
</head>
<body>
<f:form action="newTeam" method="post" modelAttribute="team">
<f:checkboxes items="${players}" path="players" itemLabel="name" itemValue="nodeId" delimiter="<br/>"/>
<input type="submit" value="Submit">
</f:form>
</body>
</html>

One issue that I see is that you inject PlayerRepository inside PlayerPropertyEditor, which has no effect, since it is not in a Spring context. You should pass it through a constructor. And then inject it in the Controller
PlayerPropertyEditor
public class PlayerPropertyEditor extends PropertyEditorSupport
{
private PlayerRepository playerRepo;
public PlayerPropertyEditor(PlayerRepository playerRepo) {
this.playerRepo = playerRepo;
}
// other methods
}
inside Controller
#Autowired
private PlayerRepository playerRepo;
#InitBinder
public void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(Player.class, new PlayerPropertyEditor(playerRepo));
}
Secondly, and I guess that this is the main issue, is that you should override equals and hashCode for your Player class. I haven't tested that, but I rely on this answer

Related

not able to see spring mvc validation error messages

I am new to spring MVC. To practice out my skills I made a sample form whose elements gets populated through respective controller. Now to check the validation part, I used all methodologies through annotations i.e. #NotNull, #Size, #Valid, #ModelAttribute, and BindingResult object. Below are the files I am using. I was following every necessary aspect, but don't know why am I not able to see RED colored validation messages.
Student class
package com.sikka.springmvcworking.custombeans;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Student {
private String firstName;
#NotNull
#Size(min=1,message="is required")
private String lastName;
private String country;
private String course;
private String[] knownOs;
private String[] coutries;
private Map<String,String> countryMap;
private Map<String,String> courseMap;
private Map<String,String> kosMap;
public Student() {
}
public Student(String firstName, String lastName, String country, String course, String[] knownOs, String[] coutries,
Map<String, String> countryMap, Map<String, String> courseMap, Map<String, String> kosMap) {
this.firstName = firstName;
this.lastName = lastName;
this.country = country;
this.course = course;
this.knownOs = knownOs;
this.coutries = coutries;
this.countryMap = countryMap;
this.courseMap = courseMap;
this.kosMap = kosMap;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Map<String, String> getCountryMap() {
return countryMap;
}
public void setCountryMap(Map<String, String> countryMap) {
this.countryMap = countryMap;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String[] getKnownOs() {
return knownOs;
}
public void setKnownOs(String[] knownOs) {
this.knownOs = knownOs;
}
public String[] getCoutries() {
return coutries;
}
public void setCoutries(String[] coutries) {
this.coutries = coutries;
}
public Map<String, String> getCourseMap() {
return courseMap;
}
public void setCourseMap(Map<String, String> courseMap) {
this.courseMap = courseMap;
}
public Map<String, String> getKosMap() {
return kosMap;
}
public void setKosMap(Map<String, String> kosMap) {
this.kosMap = kosMap;
}
}
Student Controller class
package com.sikka.springmvcworking.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.*;
import javax.validation.Valid;
import com.sikka.springmvcworking.custombeans.Student;
#Controller
#RequestMapping("stu")
public class StudentController {
#RequestMapping("studentForm")
public String getStudentForm(Model model) {
Student student = new Student();
Map<String,String> countryMap = new LinkedHashMap<String,String>();
countryMap.put("IN", "INDIA");
countryMap.put("BR", "BRAZIL");
countryMap.put("MX", "MEXICO");
student.setCountryMap(countryMap);
Map<String,String> courseMap = new LinkedHashMap<String,String>();
courseMap.put("java", "JAVA");
courseMap.put(".net", ".NET");
courseMap.put("php", "PHP");
courseMap.put("andr", "ANDROID");
student.setCourseMap(courseMap);
Map<String,String> kosMap = new LinkedHashMap<String,String>();
kosMap.put("win", "WINDOWS");
kosMap.put("lnx", "LINUX");
kosMap.put("mac", "MACINTOSH");
student.setKosMap(kosMap);
model.addAttribute("student", student);
System.out.println("inside STUDENT-FORM");
return "STUDENT-FORM";
}
#RequestMapping("processStudent")
public String outputStudent(#Valid #ModelAttribute("student") Student student, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
return "redirect:studentForm";
}
return "VIEW-STUDENT";
}
}
Student Form JSP
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<style>
.error {color: red;}
</style>
</head>
<body>
<form:form action="processStudent" modelAttribute="student">
FirstName : <form:input type="text" path="firstName" placeholder="enter your first name"/><br>
LastName : <form:input type="text" path="lastName" placeholder="enter your last name"/>
<form:errors path="lastName" cssClass="error"/><br>
select country : <form:select path="coutries">
<form:options items="${student.countryMap}"/>
</form:select><br>
select course : <form:radiobuttons path="course" items="${student.courseMap}"/><br>
known OS(s) : <form:checkboxes items="${student.kosMap}" path="knownOs"/><br>
<input type="submit" value="submit">
</form:form>
</body>
</html>
Student Submit/View Jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<br>
Student Name : ${student.firstName} ${student.lastName} <br>
Student visited countries:<br>
<c:forEach var="t" items="${student.coutries}">
<li> ${t} </li>
</c:forEach><br>
Known OS by student : <br>
<c:forEach var="t" items="${student.knownOs}">
<li> ${t} </li>
</c:forEach><br>
Student course : ${student.course}<br>
</body>
</html>
Every time to try lastName validation, I am leaving it blank. I am being redirected to same Student Form but with no error messages.
Is there any way to show validation error message in this jsp form.
I changed my Student Controller class to below code. Basically I used RedirectAttributes in my processStudent mapping. I also separate out the spring form element making maps to different methods. In studentForm I checked if student already exist (due to after validation process in processStudent mapping). Please see code:
Student-Controller class
package com.sikka.springmvcworking.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.util.*;
import javax.validation.Valid;
import com.sikka.springmvcworking.custombeans.Student;
#Controller
#RequestMapping("stu")
public class StudentController {
#RequestMapping("studentForm")
public String getStudentForm(Model model) {
Student student = new Student();
student.setCountryMap(getCountryMap());
student.setCourseMap(getCourseMap());
student.setKosMap(getKosMap());
if (!model.containsAttribute("student")) {
System.out.println("student not there");
model.addAttribute("student",student);
}
else {
System.out.println("student already there");
}
return "STUDENT-FORM";
}
#RequestMapping("processStudent")
public String outputStudent(#Valid #ModelAttribute("student") Student student, BindingResult bindingResult,RedirectAttributes attr) {
if(bindingResult.hasErrors()) {
attr.addFlashAttribute("org.springframework.validation.BindingResult.student", bindingResult);
student.setCountryMap(getCountryMap());
student.setCourseMap(getCourseMap());
student.setKosMap(getKosMap());
attr.addFlashAttribute("student", student);
return "redirect:studentForm";
}
return "VIEW-STUDENT";
}
private Map<String,String> getCountryMap(){
Map<String,String> countryMap = new LinkedHashMap<String,String>();
countryMap.put("IN", "INDIA");
countryMap.put("BR", "BRAZIL");
countryMap.put("MX", "MEXICO");
return countryMap;
}
private Map<String,String> getCourseMap(){
Map<String,String> courseMap = new LinkedHashMap<String,String>();
courseMap.put("java", "JAVA");
courseMap.put(".net", ".NET");
courseMap.put("php", "PHP");
courseMap.put("andr", "ANDROID");
return courseMap;
}
private Map<String,String> getKosMap(){
Map<String,String> kosMap = new LinkedHashMap<String,String>();
kosMap.put("win", "WINDOWS");
kosMap.put("lnx", "LINUX");
kosMap.put("mac", "MACINTOSH");
return kosMap;
}
}
Above approach solved my problem. I am not an expert in spring. Anyone out here can explain more deeply.

Getting Error while bootstraping the Spring-boot Application

Well i am developing a spring boot application by choosing view technology as jsp.But when am trying to bootstraping the spring-boot application i am getting white level error page.
Model Class
public class Person {
private String p_first_name;
private String p_last_name;
private int age;
private String city;
private String state;
private String country;
public Person(String p_first_name, String p_last_name, int age, String city, String state, String country) {
super();
this.p_first_name = p_first_name;
this.p_last_name = p_last_name;
this.age = age;
this.city = city;
this.state = state;
this.country = country;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public String getP_first_name() {
return p_first_name;
}
public void setP_first_name(String p_first_name) {
this.p_first_name = p_first_name;
}
public String getP_last_name() {
return p_last_name;
}
public void setP_last_name(String p_last_name) {
this.p_last_name = p_last_name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Controller Class
#Controller
public class PersonController {
private static ArrayList<Person> persons = new ArrayList<Person>();
static {
persons.add(new Person("kumar", "bikash", 28, "bangalore", "karnataka", "india"));
persons.add(new Person("kumar", "pratap", 24, "delhi", "delhi", "india"));
persons.add(new Person("kumar", "ravi", 29, "delhi", "delhi", "india"));
persons.add(new Person("kumar", "mangalam", 65, "delhi", "delhi", "india"));
}
#RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
public String index(Model model) {
String message = "Hello" + "Spring Boot implementation with jsp Page";
model.addAttribute("message", message);
return "index";
}
#RequestMapping(value = "/personList", method = RequestMethod.GET)
public String getPersonList(Model model) {
model.addAttribute("persons", persons);
return "personList";
}
}
application.properties
# VIEW RESOLVER CONFIGURATION
spring.mvc.view.prefix=/WEB-INF/jsp
spring.mvc.view.suffix=.jsp
jsp file
index.jsp
=========
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Integration of Spring Boot with jsp page</title>
</head>
<body>
<h1>Welcome to Spring boot</h1>
<p>This project is an Example of how to integrate Spring Boot with
jsp page.</p>
<h2>${message} </h2>
</body>
</html>
personList.jsp
==============
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Person List content Present here</title>
</head>
<body>
<h1>Person List</h1>
<div>
<table border="1">
<tr>
<th>FirstName:</th>
<th>LasttName:</th>
<th>Age:</th>
<th>city:</th>
<th>State:</th>
<th>Country:</th>
</tr>
<c:forEach items="${persons}" var=person>
<tr>
<td>${person.firstname}</td>
<td>${person.lastname}</td>
<td>${person.age }</td>
<td>${person.city }</td>
<td>${person.state }</td>
<td>${person.country }</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
Error page
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Jun 07 23:41:57 IST 2019
There was an unexpected error (type=Not Found, status=404).
No message available
well please review the below code.Help me to resolve thing where i am
getting wrong?
Are you looking to enable your own errorpage disabling the white level error page? May be this can help you.
If you do not specify any custom implementation in the configuration,
BasicErrorController bean is automatically registered in Spring Boot. You can add your implementation of ErrorController.
#Controller
public class MyErrorController implements ErrorController {
#RequestMapping("/error")
public String handleError() {
//do something like logging
return "error";
}
#Override
public String getErrorPath() {
return "/error";
}
}
1) I would suggest trying the #RestController annotation to make sure that you get at least the JSON response. (Only for Debugging)
2) After the first part is figured out, you can go back to your #Controller annotation and make sure that the string you return in the request mapping method is available as a jsp file. I would recommend trying with a single endpoint initially ("/") and having the appropriate jsp page for it.
3) If it still produces the same issue, you can refer to this post
Spring Boot JSP 404.Whitelabel Error Page
4) You can also disable and customize the default error page by following this link https://www.baeldung.com/spring-boot-custom-error-page

Spring MVC test failure

I'm writing simple integration tests for my app using the Spring MVC Test framework. I have two basic test cases:
The Add link form is filled in correctly (the URL and optional description input fields are entered) and a link is added to a database via POST and then the client is redirected to the /link URL.
The Add link form is empty, so the /links/create view is rendered and form errors from BindingResult are presented.
The testAddLink() test passes successfully, but the problem occurs with the testAddEmptyLink() test method.
In this test, the 'links/create' view should be rendered and I should get a 200 status code once the expression
result.hasErrors()
is true.
However, I'm getting a 302 response, which should be sent when there are no errors in the form (the URL has been set correctly)
It seems the test method testAddEmptyLink() cannot deal with form errors with BindingResult.
Do you have any ideas what could be the cause it cannot deal with form errors?
Thanks in advance.
Link Entity
#Entity
#Table(name = "links")
public class Link {
#Id #GeneratedValue
private Integer ID;
#Column(name = "url") #NotNull #NotEmpty #URL
private String URL;
private String description;
#Column(name="created_at", nullable = false)
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime createdAt;
#Column(name="updated_at", nullable = true)
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updatedAt;
#ManyToOne
#JoinColumn(name = "category_id")
private Category category;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
public String getURL() {
return URL;
}
public void setURL(String URL) {
this.URL = URL;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdateddAt() {
return updatedAt;
}
public void setUpdateddAt(LocalDateTime updateddAt) {
this.updatedAt = updateddAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}
LinkController
#Controller
public class LinkController {
#Autowired(required = true) #Qualifier(value = "linkService")
private LinkService linkService;
#Autowired
private CategoryService categoryService;
#RequestMapping(value = "/links")
public String getLinks(Model model) {
model.addAttribute("results", linkService.getLinks());
return "links/index";
}
#RequestMapping(value = "/links/create", method = RequestMethod.GET)
public ModelAndView showLinkForm() {
ModelAndView model = new ModelAndView("links/create");
model.addObject("link", new Link());
model.addObject("categories", categoryService.getCategories());
return model;
}
#RequestMapping(value = "/links/create", method = RequestMethod.POST)
public String addLink(#Valid #ModelAttribute("link") Link link, BindingResult result, Model model) {
if (result.hasErrors()) {
model.addAttribute("categories", categoryService.getCategories());
return "links/create";
}
linkService.addLink(link);
return "redirect:/links";
}
}
LinkControllerTest
#ContextConfiguration(classes = {AppInitializer.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class LinkControllerTest {
#Mock
private LinkService linkService;
#InjectMocks
private LinkController linkController;
private MockMvc mockMvc;
#Before
public void setUp() {
// Process mock annotations
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(linkController).build();
}
#Test
public void testAddLink() throws Exception {
mockMvc.perform(post("/links/create")
.param("URL", "http://test.com")
.param("description", "Lorem Ipsum")
.param("category.ID", "1"))
.andExpect(status().is3xxRedirection())
.andExpect(view().name("redirect:/links"));
}
#Test
public void testAddEmptyLink() throws Exception {
mockMvc.perform(post("/links/create")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.sessionAttr("link", new Link())
)
.andExpect(status().isOk())
.andExpect(view().name("links/create"))
.andExpect(forwardedUrl("/WEB-INF/views/links/create.jsp"))
.andExpect(model().attributeHasFieldErrors("link", "URL", "description"))
.andExpect(model().attribute("link", hasProperty("URL", isEmptyOrNullString())))
.andExpect(model().attribute("link", hasProperty("description", isEmptyOrNullString())));
}
}
create.jsp (View)
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Create Category</title>
</head>
<body>
<form:form action="" modelAttribute="category">
<div>
<form:label path="name">Name</form:label>
<form:input path="name" />
<form:errors path="name" cssClass="error"></form:errors>
</div>
<div>
<form:label path="description">Description</form:label>
<form:input path="description" />
<form:errors path="description" cssClass="error"></form:errors>
</div>
<div>
<input type="submit" value="Create Category">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</div>
</form:form>
</body>
</html>

Please help me out from this i am new to spring MVC :how to display images from Db using Spring mvc

my problem is how to render the images in jsp from db,
image upload was sucessfull but i am getting problem in rendering the images from DB i am using MySql Db
my Model class is
#Entity
#Table(name="photo")
public class Photo {
private int id;
private String name;
private MultipartFile file;
private byte[] imageContent;
private int imageId;
#Column(name="forId")
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="photoName")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Transient
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
#Lob
#Column(name="image",columnDefinition="blob")
public byte[] getImageContent() {
return imageContent;
}
public void setImageContent(byte[] imageContent) {
this.imageContent = imageContent;
}
}
LIst of Images jsp page (in this page only i have to display images from DB)
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:out value="${message }"></c:out>
<img src='<c:url value="/image?imageId=${imageId }"/>'/>
</body>
</html>
controller is
#Controller
public class HomeController {
#Autowired
private PhotoService photoService;
public PhotoService getPhotoService() {
return photoService;
}
public void setPhotoService(PhotoService photoService) {
this.photoService = photoService;
}
public static Logger getLogger() {
return logger;
}
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(#ModelAttribute("photo")Photo photo,Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
return "home";
}
#RequestMapping(value="/uploadPhoto",method=RequestMethod.POST)
public String uploadImage(#ModelAttribute("photo")Photo photo,#RequestParam("file")MultipartFile multipartFile,Model model) {
byte[] imageContent=null;
try {
imageContent =photo.getFile().getBytes();
}
catch(Exception e) {
e.printStackTrace();
}
System.out.println(imageContent);
photo.setImageContent(imageContent);
this.photoService.storePhoto(photo);
model.addAttribute("message", photo.getName());
model.addAttribute("imageId", photo.getImageId());
return"listOfImages";
}
#RequestMapping("/image")
public String getImages(#RequestParam("imageId")int imageId,HttpServletResponse response,Model model) {
byte[] image=null;
try {
image=this.photoService.getPhotoByPhotoId(imageId).getImageContent();
response.setContentType("image/jpg");
response.getOutputStream().write(image);
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return"listOfImages";
}
}
Dao implementation for this is
#Repository("photoDao")
public class PhotoDaoImpl implements PhotoDao {
#Autowired
private SessionFactory SessionFactory;
public SessionFactory getSessionFactory() {
return SessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
SessionFactory = sessionFactory;
}
/**
* This method is used to store the photo attributes to DB
*/
#Override
public Photo storePhoto(Photo photo) {
Session session =this.SessionFactory.getCurrentSession();
session.save(photo);
return photo;
}
#Override
public Photo getPhotoByPhotoId(int id) {
Session session =this.SessionFactory.getCurrentSession();
Photo photo =null;
photo = (Photo)session.get(Photo.class, id);
return photo;
}
}
Service implementation for this is
#Service("photoSertvice")
public class PhotoServiceImpl implements PhotoService {
#Autowired
private PhotoDao photoDao;
public PhotoDao getPhotoDao() {
return photoDao;
}
public void setPhotoDao(PhotoDao photoDao) {
this.photoDao = photoDao;
}
#Override
#Transactional
public Photo storePhoto(Photo photo) {
return this.photoDao.storePhoto(photo);
}
#Override
#Transactional
public Photo getPhotoByPhotoId(int id) {
return this.photoDao.getPhotoByPhotoId(id);
}
}
You should use either #ResponseBody or ResponseEntity to return the byte array from the 'getImages()' methid.
See this: Spring MVC: How to return image in #ResponseBody?
For example:
ResponseEntity<byte[]> getImages(#RequestParam("imageId") int imageId) {
byte[] image = ...;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(image, headers, HttpStatus.CREATED);
}
If this results in an error of kind "no converter for byte array" you'll have to register the ByteArrayHttpMessageConverter (see the above link for details). But normally it should be registered by default.

Form POST submit "The request sent by the client was syntactically incorrect."

I have no idea where I've made a mistake. I've been trying to solve this problem for hours but can't figure it out...
I'm getting HTTP Status 400 The request sent by the client was syntactically incorrect. while submiting the form with list of objects with some checkboxes to each of the objects.
Heres some of the code:
Controller:
#RequestMapping(value = "/admin/panel", method = RequestMethod.GET)
public String adminPanel(Locale locale, Model model, Form form,
HttpServletRequest request) {
FormWrapper wrapper = getFormWrapper();
model.addAttribute("listOfObjects", wrapper);
model.addAttribute("allCategories", dao.getCatsList());
return "WEB-INF/views/index/admin/home";
}
#RequestMapping(value = "/admin/saveAdmin", method = RequestMethod.POST)
public String save(Model model, #ModelAttribute(value="listOfObjects") FormWrapper listOfObjects) {
return "redirect:../index.html";
}
JSP:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<form:form modelAttribute="listOfObjects" method="POST" action="/admin/saveAdmin">
<c:forEach var="myObject" items="${listOfObjects.list}" varStatus="loop">
<form:checkboxes items="${allCategories}" path="list[${loop.index}].selectedCategories" itemLabel="name"/>
</c:forEach>
<input type="submit" value="saveTest"/>
</form:form>
FormWrapper:
public class FormWrapper {
private List<Form> list;
public List<Form> getList() {
return list;
}
public void setList(List<Form> list) {
this.list = list;
}
}
Category:
public class Category{
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long categoryId;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getCategoryId() {
return categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Category){
return getCategoryId().equals(((Category)obj).getCategoryId());
} else {
return false;
}
}
}
Any help is appreciated. I tried to change the model attribute adnotatnion to RequestParam , but in such case , my object is always null
Is it because, the FormWrapper class do not have a property "selectedCategories".
I tried removing the "selectedCategories"
Then the form was submitted successfully.
<form:checkboxes items="${allCategories}" path="list[${loop.index}]" itemLabel="name"/>
I'm not sure I understand your jsp correctly but this problem occurs when something in the jsp form does not match with the parameters you're handling at the controller.
Are you sure that "path" variable below is ok?
<form:checkboxes items="${allCategories}" path="list[${loop.index}].selectedCategories" itemLabel="name"/>

Resources