I'm developing a website using a Java Spring framework. It is an internet forum. Now, after logging in, I would like to list all threads that are currently stored in my database. I will walk you through the important part of my implementation to date first. The post is quite long, but don't get discouraged, it really is a simple, elementary problem, that anyone with rudimentary experience in web programming can solve in no time. I promise you that.
The Thread object is defined by its own class Thread. It's a standard Entity class with some fields, constructors and getters/setters.
@Entity
public class Thread {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
int _id;
private Date last_modified;
private int topics;
private String description;
private String name;
public Thread(){
}
public Thread(int _id, Date last_modified, int topics, String description,
String name) {
super();
this._id = _id;
this.last_modified = last_modified;
this.topics = topics;
this.description = description;
this.name = name;
}
public int getId() {
return _id;
}
public void setId(int _id) {
this._id = _id;
}
public Date getLast_modified() {
return last_modified;
}
public void setLast_modified(Date last_modified) {
this.last_modified = last_modified;
}
public int getTopics() {
return topics;
}
public void setTopics(int topics) {
this.topics = topics;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now, moving on to the next layer, I have the corresponding DAO interface in my DAO package:
@Transactional(propagation = Propagation.REQUIRED)
public interface ThreadDAO {
public void addThread(Thread thread);
public List<Thread> listThread();
public void removeThread (int id);
public void editThread(Thread thread);
}
and its implementation:
@Repository("threadDao")
@Transactional
public class ThreadDAOImpl implements ThreadDAO{
@Autowired
SessionFactory sessionFactory;
@Override
public void addThread(Thread thread) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().save(thread);
}
@Override
public List<Thread> listThread() {
// TODO Auto-generated method stub
return sessionFactory.getCurrentSession().createQuery("from Thread order by _id").list();
}
@Override
public void removeThread(int id) {
// TODO Auto-generated method stub
Thread thread = (Thread) sessionFactory.getCurrentSession().load(
Thread.class, id);
if (null != thread) {
sessionFactory.getCurrentSession().delete(thread);
}
}
@Override
public void editThread(Thread thread) {
// TODO Auto-generated method stub
sessionFactory.getCurrentSession().update(thread);
}
}
In order to push data to my controller, I use an autowired service:
@Transactional(propagation = Propagation.REQUIRED)
public interface ThreadService {
public void addThread(Thread thread);
public List<Thread> listThread();
public void removeThread (int id);
public void editThread(Thread thread);
}
implementation:
@Service("threadService")
@Transactional
public class ThreadServiceImpl implements ThreadService{
@Autowired
ThreadDAO threadDAO;
@Override
public void addThread(Thread thread) {
// TODO Auto-generated method stub
threadDAO.addThread(thread);
}
@Override
public List<Thread> listThread() {
// TODO Auto-generated method stub
return threadDAO.listThread();
}
@Override
public void removeThread(int id) {
// TODO Auto-generated method stub
threadDAO.removeThread(id);
}
@Override
public void editThread(Thread thread) {
// TODO Auto-generated method stub
threadDAO.editThread(thread);
}
}
Finally, I should execute Service methods in the controller:
@Controller
public class LoginController {
@Autowired
UserService userService;
@Autowired
ThreadService threadService;
@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
@RequestMapping(value = "/standard", method = RequestMethod.GET)
public ModelAndView standardView()
{
ModelAndView model = new ModelAndView();
model.setViewName("standard");
return model;
}
}
And that's where my problems begin. Because I'm terrible at web programming in general, and the concept of request mapping is ever-confusing to me. The 'standard' layout contains for now the information, that the user is logged in, and displays it's username, plus I added the list layout for my threads:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Access denied</title>
</head>
<body>
<!-- h1><spring:message code="access.denied"/></h1> -->
<h6>Logged in as: ${pageContext.request.userPrincipal.name}</h6>
<c:url value="/j_spring_security_logout" var="logoutUrl" />
<!-- csrt for log out-->
<form action="${logoutUrl}" method="post" id="logoutForm">
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
<script>
function formSubmit() {
document.getElementById("logoutForm").submit();
}
</script>
<a href="javascript:formSubmit()"> Logout</a>
<h3><spring:message code="label.threadList"/></h3>
<c:if test="${!empty threadList}">
<table class="data">
<tr>
<th><spring:message code="label.threadName"/></th>
<th><spring:message code="label.threadDescription"/></th>
<th><spring:message code="label.threadTopicCount"/></th>
<th><spring:message code="label.threadLastModified"/></th>
</tr>
<c:forEach items="${threadList}" var="thread">
<tr>
<td>${thread.name} </td>
<td>${thread.description} </td>
<td>${thread.topics}</td>
<td>${thread.last_modified}</td>
</tr>
</c:forEach>
</table>
What is missing, is the request mapping in the controller. How can I map it, so that it passes the Thread entries, record by record, and display them in this layout, along the login information?