${channels} is empty in JSP page served by Spring MVC - spring-boot

I am new to Java using STS 4 Eclipse, Java 8.
I am trying to use JSTL tags to output some values through my jsp file, however, I am not getting any output from my forEach loop in list.jsp. I am getting an output from the < p > tag directly before the loop.
Sorry for the large amount of code just didn't want to miss anything.
list.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Channels</title>
</head>
<body>
<p>Channels</p>
<c:forEach items="${channels}" var="channel">
<p>${channel.name}'s topic is ${channel.topic}</p>
<p> Link to the channel</p>
</c:forEach>
</body>
</html>
ChannelController.java
package co2103.hw1.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import co2103.hw1.Hw1Application;
import co2103.hw1.domain.Channel;
#Controller
public class ChannelController {
public List<Channel> channels;
#GetMapping("/channels")
public String channelsList(Model model) {
model.addAttribute("channels", Hw1Application.channels);
return "channels/list";
}
#RequestMapping("/newChannel")
public String newchannel(Model model) {
model.addAttribute("channel", new Channel());
return "channels/form";
}
#PostMapping("/addChannel")
public String updateChannel(#ModelAttribute Channel channel, BindingResult result) {
if (result.hasErrors()) {
return "channels/form";
}
int id = 0;
channel.setId(id);
String name = null;
channel.setName(name);
String topic = null;
channel.setTopic(topic);
Hw1Application.channels.add(channel);
return "redirect:/";
}
}
Hw1Application
package co2103.hw1;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import co2103.hw1.domain.Channel;
import co2103.hw1.domain.Show;
#SpringBootApplication
public class Hw1Application {
public static void main(String[] args) {
SpringApplication.run(Hw1Application.class, args);
}
public static List<Channel> channels = new ArrayList<>();
public static List<Show> shows = new ArrayList<>();
public void run(String... args) {
Channel channel = new Channel();
channel.setId(0);
channel.setName("Channel 1");
channel.setTopic("Nothing");
Show show = new Show();
show.setTitle("Show 1");
show.setProducer("Me");
show.setCategory("News");
show.setEpisodes(300);
Show show2 = new Show();
show.setTitle("Show 2");
show.setProducer("Me2");
show.setCategory("News2");
show.setEpisodes(300);
shows.add(show);
shows.add(show2);
channel.setShows(shows);
}
}
Channel.java
package co2103.hw1.domain;
import java.util.List;
public class Channel {
private int id;
private String name;
private String topic;
private List<Show> shows;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public List<Show> getShows() {
return shows;
}
public void setShows(List<Show> shows) {
this.shows = shows;
}
}

in the class Hw1Application ==> the method public void run(String... args) :
you need to add in the end
channels.add(channel)
Because in ChannelController.java you called channels ( that is empty in w1Application and not setted) in you #GettingMapping

So the answer that worked for me was to implements CommandLineRunner in my Hw1Application class
Hw1Application.java
#SpringBootApplication
public class Hw1Application implements CommandLineRunner {
....
}

Related

Spring - Failed to convert property value of type java.lang.String to required type

I am making a project of the Housing Association in Spring.
When I'm trying to add an object to my list of apartments I'm getting an error that is written somehow on the page:
https://s28.postimg.org/vrhy6mbd9/blad.jpg
Apartments have relation Many to One Building.
Apartment Controller:
package pl.dmcs.spoldzielnia.controllers;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import pl.dmcs.spoldzielnia.domain.Apartment;
import pl.dmcs.spoldzielnia.service.ApartmentService;
import pl.dmcs.spoldzielnia.service.BuildingService;
#Controller
#SessionAttributes
public class ApartmentController {
#Autowired
ApartmentService apartmentService;
#Autowired
BuildingService buildingService;
#RequestMapping("admin/apartment")
public String listApartment(Map<String, Object> map, HttpServletRequest request) {
int apartmentId = ServletRequestUtils.getIntParameter(request, "apartmentId" , -1);
if (apartmentId > 0)
{
Apartment apartment = apartmentService.getApartment(apartmentId);
apartment.setBuilding(buildingService.getBuilding(apartmentService.getApartment(apartmentId).getBuilding().getId()));
map.put("selectedBuilding", apartmentService.getApartment(apartmentId).getBuilding().getId());
map.put("apartment", apartment);
}
else
map.put("apartment", new Apartment());
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
#RequestMapping(value = "admin/addApartment", method = RequestMethod.POST)
public String addContact(#ModelAttribute("apartment") Apartment apartment, BindingResult result,
HttpServletRequest request, Map<String, Object> map) {
if (result.getErrorCount()==0)
{
if (apartment.getId()==0)
{
if (apartment.getBuilding().getId() > 0)
apartment.setBuilding(buildingService.getBuilding(apartment.getBuilding().getId()));
apartmentService.addApartment(apartment);
}
else
{
apartmentService.editApartment(apartment);
}
return "redirect:/admin/apartment.html";
}
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
#RequestMapping("admin/delete/apartment/{apartmentId}")
public String deleteApartment(#PathVariable("apartmentId") Integer apartmentId) {
apartmentService.removeApartment(apartmentId);
return "redirect:/admin/apartment.html";
}
// #RequestMapping("/apartment")
// public ModelAndView showContacts() {
//
// return new ModelAndView("apartment", "command", new Apartment());
// }
Domain:
package pl.dmcs.spoldzielnia.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="apartment")
public class Apartment {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
int id;
#Column(name="apartmentNumber", nullable=false)
private String number;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#ManyToOne
private Building building;
public Building getBuilding() {
return building;
}
public void setBuilding(Building building) {
this.building = building;
}
}
}
Building Service Implementation:
package pl.dmcs.spoldzielnia.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pl.dmcs.spoldzielnia.dao.BuildingDAO;
import pl.dmcs.spoldzielnia.domain.Building;
import pl.dmcs.spoldzielnia.domain.Building;
#Service
#Transactional
public class BuildingServiceImpl implements BuildingService{
#Autowired
BuildingDAO buildingDAO;
#Transactional
public void addBuilding(Building building) {
buildingDAO.addBuilding(building);
}
#Transactional
public List<Building> listBuilding() {
return buildingDAO.listBuilding();
}
#Transactional
public Building getBuilding(int id) {
return buildingDAO.getBuilding(id);
}
#Transactional
public void removeBuilding(int id) {
buildingDAO.removeBuilding(id);
}
#Transactional
public void editBuilding(Building building) {
buildingDAO.editBuilding(building);
}
}
Could you help me to solve my problem?
The problem is that you are assuming that Spring MVC is going to be able to fill your Apartment object from the data passed. From the form it looks like the Building number is 12, which probably is a unique identifier for the Building in the database, but how is Spring MVC going to know how to go to the database, retrieve the proper building object and put it into the Apartment object?
Remember that objects mapped through SpringMVC parameters are regular Java POJOs, not Hibernate attached entities. So, when the mapping occurs SpringMVC is trying to put "12" into the building attribute of type Building into your POJO (which explains the error you are getting).
You have two options:
First, you can register a custom formatter, that will use the passed id to retrieve a Building from the database:
import org.springframework.core.convert.converter.Converter;
public class BuildingIdToBuildingConverter implements Converter<String, Building> {
private BuildingService buildingService;
public BuildingIdToBuildingConverter(BuildingService buildingService) {
this.buildingService = buildingService;
}
#Override
public Building convert (String id) {
return buildingService.getBuilding(id);
}
}
And register it:
public class AppConfig extends WebMvcConfigurerAdapter {
...
#Bean
public BuildingService buildingService(){
return new BuildingService();
}
#Override
public void addFormatters (FormatterRegistry registry) {
registry.addConverter(new BuildingIdToBuildingConverter(buildingService()));
}
}
Second, do this work manually by sending the building id in a separate parameter:
#RequestMapping(value = "admin/addApartment", method = RequestMethod.POST)
public String addContact(#ModelAttribute("apartment") Apartment apartment, #RequestParam("buildingId") String buildingId, BindingResult result, HttpServletRequest request, Map<String, Object> map) {
if (result.getErrorCount()==0){
if (apartment.getId()==0){
apartment.setBuilding(buildingService.getBuilding(buildingId));
apartmentService.addApartment(apartment);
}
}
else{
apartmentService.editApartment(apartment);
}
return "redirect:/admin/apartment.html";
}
map.put("buildingList", buildingService.listBuilding());
map.put("apartmentList", apartmentService.listApartment());
return "apartment";
}
And change your HTML accordingly to send the buildingId value.

Spring MVC to REST

I have a Spring MVC aplication. I want to convert it to a RESTful
webservice, which returns a JSON response. Can somebody help me with this??
Basically, I want to convert my controller to a REST controller.
My Code :
///////////////////////////PersonController//////////////////////////////
package com.journaldev.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.service.PersonService;
#Controller
public class PersonController {
private PersonService personService;
#Autowired(required=true)
#Qualifier(value="personService")
public void setPersonService(PersonService ps){
this.personService = ps;
}
#RequestMapping(value = "/persons", method = RequestMethod.GET)
public String listPersons(Model model) {
model.addAttribute("person", new Person());
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
//For add and update person both
#RequestMapping(value= "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person p){
if(p.getId() == 0){
//new person, add it
this.personService.addPerson(p);
}else{
//existing person, call update
this.personService.updatePerson(p);
}
return "redirect:/persons";
}
#RequestMapping("/remove/{id}")
public String removePerson(#PathVariable("id") int id){
this.personService.removePerson(id);
return "redirect:/persons";
}
#RequestMapping("/edit/{id}")
public String editPerson(#PathVariable("id") int id, Model model){
model.addAttribute("person", this.personService.getPersonById(id));
model.addAttribute("listPersons", this.personService.listPersons());
return "person";
}
}
/////////////////////////////////PersonDAO/////////////////////////////
package com.journaldev.spring.dao;
import java.util.List;
import com.journaldev.spring.model.Person;
public interface PersonDAO {
public void addPerson(Person p);
public void updatePerson(Person p);
public List<Person> listPersons();
public Person getPersonById(int id);
public void removePerson(int id);
}
///////////////////////////////PersonDAOImpl/////////////////////////
package com.journaldev.spring.dao;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import com.journaldev.spring.model.Person;
#Repository
public class PersonDAOImpl implements PersonDAO {
private static final Logger logger = LoggerFactory.getLogger(PersonDAOImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf){
this.sessionFactory = sf;
}
#Override
public void addPerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(p);
logger.info("Person saved successfully, Person Details="+p);
}
#Override
public void updatePerson(Person p) {
Session session = this.sessionFactory.getCurrentSession();
session.update(p);
logger.info("Person updated successfully, Person Details="+p);
}
#SuppressWarnings("unchecked")
#Override
public List<Person> listPersons() {
Session session = this.sessionFactory.getCurrentSession();
List<Person> personsList = session.createQuery("from Person").list();
for(Person p : personsList){
logger.info("Person List::"+p);
}
return personsList;
}
#Override
public Person getPersonById(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
logger.info("Person loaded successfully, Person details="+p);
return p;
}
#Override
public void removePerson(int id) {
Session session = this.sessionFactory.getCurrentSession();
Person p = (Person) session.load(Person.class, new Integer(id));
if(null != p){
session.delete(p);
}
logger.info("Person deleted successfully, person details="+p);
}
}
//////////////////////////////////Person(Model)///////////////////////
package com.journaldev.spring.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Entity bean with JPA annotations
* Hibernate provides JPA implementation
* #author pankaj
*
*/
#Entity
#Table(name="PERSON")
public class Person {
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
private String country;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public String toString(){
return "id="+id+", name="+name+", country="+country;
}
}
///////////////////////////////////PersonService///////////////////
package com.journaldev.spring.service;
import java.util.List;
import com.journaldev.spring.model.Person;
public interface PersonService {
public void addPerson(Person p);
public void updatePerson(Person p);
public List<Person> listPersons();
public Person getPersonById(int id);
public void removePerson(int id);
}
//////////////////////////////ServiceImpl////////////////////////////
package com.journaldev.spring.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.journaldev.spring.dao.PersonDAO;
import com.journaldev.spring.model.Person;
#Service
public class PersonServiceImpl implements PersonService {
private PersonDAO personDAO;
public void setPersonDAO(PersonDAO personDAO) {
this.personDAO = personDAO;
}
#Override
#Transactional
public void addPerson(Person p) {
this.personDAO.addPerson(p);
}
#Override
#Transactional
public void updatePerson(Person p) {
this.personDAO.updatePerson(p);
}
#Override
#Transactional
public List<Person> listPersons() {
return this.personDAO.listPersons();
}
#Override
#Transactional
public Person getPersonById(int id) {
return this.personDAO.getPersonById(id);
}
#Override
#Transactional
public void removePerson(int id) {
this.personDAO.removePerson(id);
}
}
First you have to add Jackson Databind dependency in your pom file then you can define your rest controller for exemple :
#RestController
public class PersonRestService {
#Autowired
private PersonService personService ;
#RequestMapping(value="/persons",method=RequestMethod.POST)
public Person addPerson(#RequestBody Person Person) {
return personService.addPerson(Person);
}
#RequestMapping(value="/persons",method=RequestMethod.Delete)
public void deletePerson(int code) {
personService.deletePerson(code);
}
#RequestMapping(value="/persons",method=RequestMethod.GET)
public Person getPerson(#RequestParam int code) {
return personService.getPersonById(code);
}
#RequestMapping(value="/allPersons",method=RequestMethod.GET)
public List<Person> getAllPerson() {
return personService.getAllPerson();
}
}
Its easy, what you need to do is add a response in JSON for all request which need it.
The annotation is #ResponseBody and you can return any object, jackson will serialize it to json format for you.
For example in your code:
#RequestMapping("/remove/{id}")
#ResponseBody
public boolean removePerson(#PathVariable("id") int id){
this.personService.removePerson(id);
//true if everything was OK, false if some exception
return true;
}
...
#RequestMapping(value = "/persons", method = RequestMethod.GET)
#ResponseBody
public List<Person> listPersons(Model model) {
return this.personService.listPersons();
}
You only need to modify your controller, to make it RESTFul
Also you will have to add logic to your JS code to handle the new responses values.
Simply use the annotation #RestController.
You can also refer to previously asked question on this link
Difference between spring #Controller and #RestController annotation

Java MessageDriven Beans Issue

i need help with this kind of issue:
Exception attempting to inject Unresolved Message-Destination-Ref web.News/queue#java.lang.String#null into class web.News: Lookup failed for 'java:comp/env/web.News/queue' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
This is my Entity Class
package ejb;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
*
* #author Maciej1
*/
#Entity
public class NewsItem implements Serializable {
private String heading;
private String body;
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof NewsItem)) {
return false;
}
NewsItem other = (NewsItem) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "ejb.NewsItem[ id=" + id + " ]";
}
/**
* #return the heading
*/
public String getHeading() {
return heading;
}
/**
* #param heading the heading to set
*/
public void setHeading(String heading) {
this.heading = heading;
}
/**
* #return the body
*/
public String getBody() {
return body;
}
/**
* #param body the body to set
*/
public void setBody(String body) {
this.body = body;
}
}
here is my Message-Driven Beans class:
package ejb;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
*
* #author Maciej1
*/
#MessageDriven(mappedName = "jms/NewsQueue", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class NewsMDB implements MessageListener {
#PersistenceContext(unitName = "MDBLabPU")
private EntityManager em;
public NewsMDB() {
}
#Override
public void onMessage(Message message) {
ObjectMessage msg = null;
try {
if (message instanceof ObjectMessage) {
msg = (ObjectMessage) message;
NewsItem e = (NewsItem) msg.getObject();
saveObject(e);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
public void saveObject(Object object) {
em.persist(object);
}
}
In the end my class to communication with JavaServer Faces:
package web;
import ejb.NewsItem;
import ejb.NewsItemFacadeLocal;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
/**
*
* #author Maciej1
*/
#Named
#RequestScoped
public class News {
#EJB
private NewsItemFacadeLocal newsItemFacade;
#Resource(lookup="java:comp/DefaultJMSConnectionFactory")
private ConnectionFactory connectionFactory;
#Resource(lookup="jms/NewsQueue")
private javax.jms.Queue queue;
private String headingText = "headingText";
private String bodyText = "bodyText";
void sendNewsItem(String heading, String body)
{
try {
Connection connection = connectionFactory.createConnection();
Session session;
session = connection.createSession(true, 0);
MessageProducer messageProducer = session.createProducer(queue);
ObjectMessage message = session.createObjectMessage();
NewsItem e = new NewsItem();
e.setHeading(heading);
e.setBody(body);
message.setObject(e);
messageProducer.send(message);
messageProducer.close();
connection.close();
} catch (JMSException
ex) {
ex.printStackTrace();
}
}
public List<NewsItem> getNewsItems()
{
return newsItemFacade.findAll();
}
public String submitNews(){
sendNewsItem(getHeadingText(), getBodyText());
return null;
}
Can you help me with this issue?
I discover that problem can be probable in Faces file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:outputText></h:outputText>
<h:inputText value="#{news.headingText}" id="headingInputText"></h:inputText>
<h:outputText></h:outputText>
<h:inputText value="#{news.bodyText}" id="bodyInputText"></h:inputText>
<h:commandButton value="Submit" id="submitButton"></h:commandButton>
</h:form>
</h:body>
</html>
I had to change from this declaration:
#Resource(lookup="jms/NewsQueue")
private javax.jms.Queue queue;
to this:
#Resource(lookup="java:app/jms/NewsQueue")
private javax.jms.Queue queue;
It's generate from NetBeans 8.1 probably differently. Now this code work perfectly

How to display form validation constraints message on GWT Material inputs using Editor and Validation Framework from Presenter's class?

I use:
Gwt-platform
Gwt Validation
Gwt UiEditor framework
Gwt Material inputs
After constraints validation I would like to display error messages. This is supported by gwt material inputs, like MaterialTextBox using method:  materialTextBox.setError("Please provide your name");
The problem is that it can be only executed from view class:
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
public void test() {}
}
But I do all my editor/validation action in Presenter, and I do not have there any View connection I could use:
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel("","");
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
StringBuilder errorBuilder = new StringBuilder();
for (EditorError error : editorDriver.getErrors()) {
errorBuilder.append(error.getMessage() + "\n");
}
MaterialToast.fireToast(errorBuilder.toString());
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
}
I think that I should add an interface where I will declare methods to access inputs in view. And do implementation of that. But I don't know how. Please help me.
I've make it working. But really I am not quite sure what did happened that it start to work. So I will just share my working code:
Presenter
package pl.korbeldaniel.cms.client.login;
import java.util.ArrayList;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;
import gwt.material.design.client.ui.MaterialToast;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import com.gwtplatform.mvp.client.HasUiHandlers;
import pl.korbeldaniel.cms.client.editor.BeanEditView;
import pl.korbeldaniel.cms.client.model.LoginModel;
import pl.korbeldaniel.cms.client.place.NameTokens;
import pl.korbeldaniel.cms.client.service.LoginService;
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers {
#ProxyStandard
#NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter> {}
public interface MyView extends BeanEditView<LoginModel>, HasUiHandlers<LoginUiHandlers> {}
public static final Type<RevealContentHandler<?>> SLOT_Login = new Type<RevealContentHandler<?>>();
// Editor
private SimpleBeanEditorDriver<LoginModel, ?> editorDriver;
private static final LoginService service = GWT.create(LoginService.class);
private LoginModel model = new LoginModel();
#Override
public void onLoginButtonClick() {
if (editorDriver.isDirty()) {
model = editorDriver.flush();
validateModel();
if (editorDriver.hasErrors()) {
MaterialToast.fireToast("Errors occur");
} else {
service.login(
model, new MethodCallback<Integer>() {
#Override
public void onSuccess(Method method, Integer response) {
MaterialToast.fireToast("Succefully set info. status code: " + response);
}
#Override
public void onFailure(Method method, Throwable exception) {
MaterialToast.fireToast("Error setting");
}
});
}
} else {
MaterialToast.fireToast("Data has not changed");
}
}
private void validateModel() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<LoginModel>> violations = validator.validate(model);
GWT.log(String.valueOf(violations.size()));
if (violations.size() > 0) {
editorDriver.setConstraintViolations(new ArrayList<ConstraintViolation<?>>(violations));
}
model.validate();
}
#Inject
LoginPresenter(EventBus eventBus,MyView view, MyProxy proxy) {
super(eventBus, view, proxy, RevealType.Root);
getView().setUiHandlers(this);
editorDriver = getView().createEditorDriver();
editorDriver.edit(model);
}
public enum EditorMode {
VIEW, EDIT, CREATE
};
}
Ui Handler
package pl.korbeldaniel.cms.client.login;
import com.gwtplatform.mvp.client.UiHandlers;
interface LoginUiHandlers extends UiHandlers {
void onLoginButtonClick();
}
ValidatorFactory
package pl.korbeldaniel.cms.client.login;
import javax.validation.Validator;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.validation.client.AbstractGwtValidatorFactory;
import com.google.gwt.validation.client.GwtValidation;
import com.google.gwt.validation.client.impl.AbstractGwtValidator;
public final class SampleValidatorFactory extends AbstractGwtValidatorFactory {
/**
* Validator marker for the Validation Sample project. Only the classes and
* groups listed in the {#link GwtValidation} annotation can be validated.
*/
#GwtValidation(LoginModel.class)
public interface GwtValidator extends Validator {
}
#Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
View
package pl.korbeldaniel.cms.client.login;
import gwt.material.design.client.ui.MaterialButton;
import gwt.material.design.client.ui.MaterialCheckBox;
import gwt.material.design.client.ui.MaterialTextBox;
import javax.inject.Inject;
import pl.korbeldaniel.cms.client.model.LoginModel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.SimpleBeanEditorDriver;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.gwtplatform.mvp.client.ViewWithUiHandlers;
public class LoginView extends ViewWithUiHandlers<LoginUiHandlers> implements LoginPresenter.MyView {
interface Binder extends UiBinder<Widget, LoginView> {}
/** The driver to link the proxy bean with the view. */
public interface EditorDriver extends SimpleBeanEditorDriver<LoginModel, LoginView> { }
#UiField MaterialTextBox email;
#UiField MaterialTextBox password;
#UiField MaterialButton loginButton;
#UiField MaterialCheckBox keepMeLoggedInCheckbox;
#Inject
LoginView(Binder uiBinder) {
initWidget(uiBinder.createAndBindUi(this));
addClickHandlerToLoginButton();
}
//#UiHandler("loginButton")
private void onLoginButtonClick(ClickEvent e){
getUiHandlers().onLoginButtonClick();
}
private void addClickHandlerToLoginButton() {
loginButton.addClickHandler(new ClickHandler() {
#Override public void onClick(ClickEvent event) {
onLoginButtonClick(event);
}
});
}
#Override
public SimpleBeanEditorDriver<LoginModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
}
View Binder
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:m="urn:import:gwt.material.design.client.ui"
xmlns:e="urn:import:pl.korbeldaniel.cms.client.login">
<m:MaterialRow ui:field="loginWidget">
<m:MaterialColumn grid="s12 m4 l4" offset="l4 m4" >
<m:MaterialTitle title="Login" description="Please provide your account credentials."/>
<m:MaterialPanel padding="5" shadow="1" addStyleNames="{style.panel}">
<m:MaterialPanel addStyleNames="{style.fieldPanel}">
<!-- <m:MaterialImage url="http://b.vimeocdn.com/ps/339/488/3394886_300.jpg" type="CIRCLE" addStyleNames="{style.imgProfile} z-depth-1"/> -->
<m:MaterialTextBox ui:field="email" type="EMAIL" placeholder="Email"/>
<m:MaterialTextBox ui:field="password" type="PASSWORD" placeholder="Password"/>
<m:MaterialRow addStyleNames="{style.rowAction}">
<m:MaterialColumn grid="s12 m12 l6">
<m:MaterialCheckBox ui:field="keepMeLoggedInCheckbox" text="Keep me logged in"/>
</m:MaterialColumn>
</m:MaterialRow>
<m:MaterialButton ui:field="loginButton" waves="LIGHT" text="Log In" width="100%"/>
</m:MaterialPanel>
</m:MaterialPanel>
</m:MaterialColumn>
</m:MaterialRow>
</ui:UiBinder>

SpringData: How Map AngularJS page with #RepositoryRestResource?

I follow this tutorial about Data Accessing:
http://spring.io/guides/gs/accessing-data-rest/
So, I have this structure
http://i.stack.imgur.com/wUnrx.png
"Project" is the Model
package Serveur;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
private String mail;
private String password;
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
And the interface "ProjectRepository", which implemented directly by the "#RepositoryRestResource" annotation
package Serveur;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
#RepositoryRestResource(collectionResourceRel = "jsonProjects", path = "jsonProjects")
public interface ProjectRepository extends CrudRepository<Project, Integer> {
List<Project> findById(#Param("name") String name);
}
The "Home Controller" contains a #RequestMapping Annotation and redirects the user to "index" page :
package Serveur;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HomeController {
#RequestMapping("/")
public String index()
{
return "index";
}
}
But, when I connect to localhost:8080/ , the index page does not display but this:
{
_links: {
jsonProjects: {
href: "http://localhost:8080/jsonProjects{?page,size,sort}",
templated: true
}
}
}
The problem is that the #RepositoryRestResource annotation binds to "/". To fix your issue, edit Application.java and add this function:
#Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
super.configureRepositoryRestConfiguration(config);
try {
config.setBaseUri(new URI("/api"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
Your HomeController will not bind to "/" and your API's will be available at "/api"
Here is the answer:
By default all Repository search function comes after search keyword. So in your case URL will be something like:
http://localhost:PORT/APP/jsonProjects/search/findById?name=NAME
See my working example and blog for the same:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with-hibernate-no-controller
Hope this helps.

Resources