0

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?

user4359659
  • 149
  • 2
  • 4
  • 18

1 Answers1

1

Just add object to ModelAndView instance in controller:

model.addObject("threadList", threadService.listThread());

and it should be accessible in JSP page.

Also please don't use transactions on DAO layer - use it only on Service layer instead. See this post.

Community
  • 1
  • 1
kurochenko
  • 1,214
  • 3
  • 19
  • 43
  • I removed Transactional. And did like you said, but I get: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'thread' available as request attribute – user4359659 Feb 04 '15 at 22:44
  • Is the code the same you're posting in question, because in your code `thread` object should be created by `forEach` loop. Is it possible that you use `thread` variable outside the `forEach` loop? – kurochenko Feb 05 '15 at 10:31