Spring : timely/late binding of #ModelAttribute - spring

I'm using the following code to bind the users to the model [to be used in the view/jsp]:
#ModelAttribute("users")
public Collection<User> populateUsers() {
return userService.findAllUsers();
}
But sometimes I just need to load few users with a particular Role, which I'm trying by using the following code:
int role = 2; //this is being set in a Controller within a method #RequestMapping(method = RequestMethod.GET) public String list(
#ModelAttribute("users")
public Collection<User> populateUsers() {
if(role == 2)
return userService.findAllUsersByRole(role);
else
return userService.findAllUsers();
}
but the populateUsers is always called at the start of the controller, before the role is set in list method, Could you please help me on how to set the users [something like late binding]
Regards
-- adding code
#Controller
#RequestMapping("/users")
public class UserController {
#Autowired
UserService userService;
#RequestMapping(method = RequestMethod.POST)
public String create(#Valid User user, BindingResult bindingResult,
Model uiModel, HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
uiModel.addAttribute("user", user);
addDateTimeFormatPatterns(uiModel);
return "users/create";
}
uiModel.asMap().clear();
userService.saveUser(user);
return "redirect:/users/"
+ encodeUrlPathSegment(user.getId().toString(),
httpServletRequest);
}
#RequestMapping(params = "form", method = RequestMethod.GET)
public String createForm(Model uiModel) {
uiModel.addAttribute("user", new User());
addDateTimeFormatPatterns(uiModel);
return "users/create";
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String show(#PathVariable("id") Long id, Model uiModel) {
addDateTimeFormatPatterns(uiModel);
uiModel.addAttribute("user", userService.findUser(id));
return "users/show";
}
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET)
public String updateForm(#PathVariable("id") Long id, Model uiModel) {
uiModel.addAttribute("user", userService.findUser(id));
addDateTimeFormatPatterns(uiModel);
return "users/update";
}
#ModelAttribute("users")
public Collection<User> populateUsers() {
return userService.findAllUsers();
}
#ModelAttribute("userroles")
public Collection<UserRole> populateUserRoles() {
return Arrays.asList(UserRole.class.getEnumConstants());
}
void addDateTimeFormatPatterns(Model uiModel) {
uiModel.addAttribute(
"user_modified_date_format",
DateTimeFormat.patternForStyle("M-",
LocaleContextHolder.getLocale()));
}
}
#PathVariable("id") Long id is the ID I require in populateUsers, hope it is clear.

If role is in the current request, this method binding role to variable role.
#ModelAttribute("users")
public Collection<User> populateUsers(#RequestParam(required=false) Integer role) {
if(role != null && role == 2)
return userService.findAllUsersByRole(role);
else
return userService.findAllUsers();
}

Setting the model attribute in the required method has solved my issue:
model.addAttribute("users", return userService.findAllUsersByRole(role));
Thanks!

Related

How to list data from database in a web page in spring framework

I have created a database called student base on the tutorial provided by tutorials point PDF, they have covered how to map the form and insert values in to the database using controllers, but they have not explained how to display the data from the database on to the webpage.
My code to list all students.
#Override
public List<Student> listStudents() {
String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(SQL, new StudentMapper());
return students;
}
How to call this from my controller in spring and return the list to my webpage.
My contoller is given below
#Controller
public class StudentController {
#RequestMapping(value = "/student", method = RequestMethod.GET)
public ModelAndView student()
{
return new ModelAndView("student", "command", new Student());
}
#RequestMapping(value = "/addStudent", method = RequestMethod.POST)
public String addStudent(#ModelAttribute("SpringWeb")Student student, ModelMap model)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");
studentJDBCTemplate.create(student.getName(), student.getAge());
model.addAttribute("name", student.getName());
model.addAttribute("age", student.getAge());
model.addAttribute("msg", "Student Enrolled");
return "result";
}
// How to write the listing controller?
}
From the details you provide ,
public String ListStudents(ModelMap model)
{
List<Student> list= YourServiceClassObj.listStudents();
model.addAttribute("result", list);
return "View Name here";
}
public class AccountDAO {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
public Account getAll(String user, String pass) {
String query = "SELECT * FROM dbo.USERR WHERE username=? AND password =?";
try {
conn = new DBContext().getConnection();
ps = conn.prepareStatement(query);
ps.setString(1, user);
ps.setString(2, pass);
rs = ps.executeQuery();
while (rs.next()) {
return new Account(rs.getString(1),
rs.getString(2),
rs.getString(3));
}
} catch (Exception e) {
}
return null;
}
}
your controller and service methods should be like this .and then in the view use the controller returned attribute students.
#Controller
#RequestMapping(value = "/students", method = RequestMethod.GET)
public String students(ModelMap model)
{
List<Student> students= studentService.getStudents();
model.addAttribute("students", students);
return "student/studentList.html";
}
Service :
public interface StudentService {
List<Student> getStudents();
}
#Service
public class StudentServiceImpl implements StudentService {
#Override
public List<Student> getStudents() {
return studentRepository.findAll();
}

how to return not found status from spring controller

I have following spring controller code and want to return not found status if user is not found in database, how to do it?
#Controller
public class UserController {
#RequestMapping(value = "/user?${id}", method = RequestMethod.GET)
public #ResponseBody User getUser(#PathVariable Long id) {
....
}
}
JDK8 approach:
#RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(#PathVariable Long id) {
return Optional
.ofNullable( userRepository.findOne(id) )
.map( user -> ResponseEntity.ok().body(user) ) //200 OK
.orElseGet( () -> ResponseEntity.notFound().build() ); //404 Not found
}
Change your handler method to have a return type of ResponseEntity. You can then return appropriately
#RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(#PathVariable Long id) {
User user = ...;
if (user != null) {
return new ResponseEntity<User>(user, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Spring will use the same HttpMessageConverter objects to convert the User object as it does with #ResponseBody, except now you have more control over the status code and headers you want to return in the response.
With the latest update you can just use
return ResponseEntity.of(Optional<user>);
The rest is handled by below code
/**
* A shortcut for creating a {#code ResponseEntity} with the given body
* and the {#linkplain HttpStatus#OK OK} status, or an empty body and a
* {#linkplain HttpStatus#NOT_FOUND NOT FOUND} status in case of a
* {#linkplain Optional#empty()} parameter.
* #return the created {#code ResponseEntity}
* #since 5.1
*/
public static <T> ResponseEntity<T> of(Optional<T> body) {
Assert.notNull(body, "Body must not be null");
return body.map(ResponseEntity::ok).orElse(notFound().build());
}
public static ResponseEntity of(Optional body)
A shortcut for creating a ResponseEntity with the given body and the OK status, or an empty body and a NOT FOUND status in case of an Optional.empty() parameter.
#GetMapping(value = "/user/{id}")
public ResponseEntity<User> getUser(#PathVariable final Long id) {
return ResponseEntity.of(userRepository.findOne(id)));
}
public Optional<User> findOne(final Long id) {
MapSqlParameterSource paramSource = new MapSqlParameterSource().addValue("id", id);
try {
return Optional.of(namedParameterJdbcTemplate.queryForObject(SELECT_USER_BY_ID, paramSource, new UserMapper()));
} catch (DataAccessException dae) {
return Optional.empty();
}
}
it could be shorter using Method Reference operator ::
#RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(#PathVariable Long id) {
return Optional.ofNullable(userRepository.findOne(id))
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
Need use ResponseEntity or #ResponseStatus, or with "extends RuntimeException"
#DeleteMapping(value = "")
public ResponseEntity<Employee> deleteEmployeeById(#RequestBody Employee employee) {
Employee tmp = employeeService.deleteEmployeeById(employee);
return new ResponseEntity<>(tmp, Objects.nonNull(tmp) ? HttpStatus.OK : HttpStatus.NOT_FOUND);
}
or
#ResponseStatus(value=HttpStatus.NOT_FOUND, reason="was Not Found")

Assitance regarding JUnit Testing for Spring Controller Dao

I am new to Junit.Please help me to test Spring hibernate Controller with ContentType is application/json
Below is my Controller
#Controller
#RequestMapping(value="/users")
public class UserServiceImpl implements UserService{
private static Logger logger = Logger.getLogger(UserService.class);
private UserDao userDao;
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#RequestMapping(method = RequestMethod.POST,headers = "content-type=application/json")
#ResponseBody
public long addUser(#RequestBody UserForm user) {
logger.info("Creating new user {}"+ user);
return userDao.create(user);
}
#RequestMapping(value = "/{userId}", method = RequestMethod.GET)
#ResponseBody
public User findUser(#PathVariable(value = "userId") String userId) {
logger.info("Reading user with id {}"+ userId);
User user = userDao.find(userId);
Validate.isTrue(user != null, "Unable to find user with id: " + userId);
return user;
}
#RequestMapping(value = "/{userId}", method = RequestMethod.PUT,headers = "content-type=application/json")
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateUser(#PathVariable(value = "userId") String userId, #RequestBody UserForm user) {
logger.info("Updating user with id {} with {}"+ userId +"->"+ user);
Validate.isTrue(userId.equals(user.getUserId()), "userId doesn't match URL userId: " + user.getUserId());
userDao.update(user);
}
#RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void deleteUser(#PathVariable(value = "userId") String userId) {
logger.info("Deleting user with id {}"+ userId);
userDao.delete(userId);
}
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
public List<User> list() {
logger.info("Listing users");
return new ArrayList<User>(userDao.getUsers());
}
}
Can any one Send me the Junit Test case for Any one of the CRUD operations.
Thanks in Advance
Srikanth
If you just want to test your controller, then I would say that mock the DAO. You don't have to care about content types and such because Spring takes care of them. You are interested what the controller method is returning. If you want to test your DAO that User actually is saved to database, that's another story.
But just for testing that controller does what it is supposed to, something like this for example. Example uses EasyMock. I haven't compiled this example so it might have typos.
import static org.easymock.EasyMock.createNiceMock;
public class ControllerTest {
private UserServiceImpl userService;
private UserDao userDaoMock;
#Before
public void setup() {
userDaoMock = createNiceMock(UserDao.class);
userService = new UserServiceImpl();
userSerivce.setUserDao(userDaoMock);
}
#Test
public void testAddUser() {
UserForm userForm = new UserForm();
long expectedResult = 5L;
expect(userDaoMock.create(userForm)).andReturn(expectedResult);
replay(userDaoMock);
long actualResult = userService.addUser(userForm);
verify(userDaoMock);
assertEquals(expectedResult, actualResult);
}
}

how does we enhance presistent class

AS I am new to JDO and datastore
I have set up a simple Google App Engine project based on Spring Framework to Perform Basic CRUD operation.
When I run my Application Its Show's
Persistent class "Class com.pandian.model.Customer does not seem to have been enhanced. You may want to rerun the enhancer and check for errors in the output." has no table in the database, but the operation requires it. Please check the specification of the MetaData for this class.
Customer
#PersistenceCapable
public class Customer {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
#Persistent
private String name;
#Persistent
private String email;
#Persistent
private Date date;
public Key getKey() {
return key;
}
public void setKey(Key key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Customer() {
super();
}
Controller
#Controller
#RequestMapping("/customer")
public class CustomerController {
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String getAddCustomerPage(ModelMap model) {
return "add";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView add(HttpServletRequest request, ModelMap model) {
String name = request.getParameter("name");
String email = request.getParameter("email");
Customer c = new Customer();
c.setName(name);
c.setEmail(email);
c.setDate(new Date());
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(c);
} finally {
pm.close();
}
return new ModelAndView("redirect:list");
}
#RequestMapping(value = "/update/{name}", method = RequestMethod.GET)
public String getUpdateCustomerPage(#PathVariable String name,
HttpServletRequest request, ModelMap model) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Query q = pm.newQuery(Customer.class);
q.setFilter("name == nameParameter");
q.setOrdering("date desc");
q.declareParameters("String nameParameter");
try {
#SuppressWarnings("unchecked")
List<Customer> results = (List<Customer>) q.execute(name);
if (results.isEmpty()) {
model.addAttribute("customer", null);
} else {
model.addAttribute("customer", results.get(0));
}
} finally {
q.closeAll();
pm.close();
}
return "update";
}
#RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(HttpServletRequest request, ModelMap model) {
String name = request.getParameter("name");
String email = request.getParameter("email");
String key = request.getParameter("key");
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Customer c = pm.getObjectById(Customer.class, key);
c.setName(name);
c.setEmail(email);
c.setDate(new Date());
} finally {
pm.close();
}
// return to list
return new ModelAndView("redirect:list");
}
#RequestMapping(value = "/delete/{key}", method = RequestMethod.GET)
public ModelAndView delete(#PathVariable String key,
HttpServletRequest request, ModelMap model) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Customer c = pm.getObjectById(Customer.class, key);
pm.deletePersistent(c);
} finally {
pm.close();
}
PMF
public final class PMF {
private static final PersistenceManagerFactory pmfInstance = JDOHelper
.getPersistenceManagerFactory("transactions-optional");
private PMF() {
}
list//JSP
....
<%
if(request.getAttribute("customerList")!=null){
List<Customer> customers =
(List<Customer>)request.getAttribute("customerList");
if(!customers.isEmpty()){
for(Customer c : customers){
%>
<tr>
<td><%=c.getName() %></td>
<td><%=c.getEmail() %></td>
...
Any body help me out from this.....
When you looked at the AppEngine docs for using JDO, you would have come across
https://developers.google.com/eclipse/docs/appengine_orm
This tells you HOW to enhance classes for use with JDO.

getting null values in spring MVC controller

i am new in spring. and i am developing login application in spring mvc . while setting the values in LoginForm its is showing "null". please help me. want to get out of it!!
Any help will be appriciated.
My controller is:
#Controller
#RequestMapping("loginform.html")
public class LoginController extends MainController {
private String password;
private LoginDAO loginDAO;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#RequestMapping(method = RequestMethod.GET)
public String showForm(Map model) {
LoginForm loginForm = new LoginForm();
model.put("loginForm", loginForm);
return "loginform";
}
#RequestMapping(method = RequestMethod.POST)
public String processForm(#Valid LoginForm loginForm, BindingResult result,
Map model) {
//String userName = "Admin";
//String password = "root";
if (result.hasErrors()) {
return "loginform";
}
try {
loginForm.setUserName(userName);
loginForm.setPassword(password);
loginDAO = new LoginDAOImpl();
LoginForm tempLoginForm = loginDAO.validateUser(loginForm);
if (tempLoginForm == null) {
return "loginsuccess";
}
} catch (Exception e) {
}
model.put("loginForm", loginForm);
return "loginerror";
}
}
You must not set the username and password in the process form method, you must read it form the form object.
String userName = login form.getUserName();

Resources