Spring #SessionAttributes not working - spring

My Controller class
#Controller
#SessionAttributes("basschoolsform")
public class SchoolStudentsConfirmationContrl
{
Below method accepts ac_year and gets data accordingly and redirects to page showreport
#RequestMapping(value="/SchoolStudentConfirmation.getData",method=RequestMethod.GET)
public ModelAndView BASyearWiseReport(#ModelAttribute BASSchoolsForm basschoolsform,HttpServletRequest request)
{
ModelAndView mav=new ModelAndView();
try
{
List<Object[]> result=schoolstdconfirmservice.BASyearWiseReport(request,basschoolsform);
PageHeading = "BAS Students Confirmation for the Academic Year:"+ basschoolsform.getAc_year()
if(!result.isEmpty())
{
mav.addObject("result",result);
}
else
{
mav.addObject("msg","NO Data Found");
}
mav.setViewName("showreportwithmenu");
}
catch(Exception e)
{
e.printStackTrace();
}
mav.addObject("basschoolsform",basschoolsform);
return mav;
}
This Method also uses ac_year and gets data and redirects to studentstatusedit
#RequestMapping(value="/SchoolStudentConfirmation.ConfirmStudentByDO",method=RequestMethod.GET)
public ModelAndView ConfirmStudentByDO(#ModelAttribute BASSchoolsForm basschoolsform,HttpServletRequest request)
{
ModelAndView mav=new ModelAndView();
System.out.println(basschoolsform.getAc_year()+" later value");
List<BASSchoolsForm> studentdata=schoolstdconfirmservice.ConfirmStudentByDO(basschoolsform,request);
if(studentdata != null && studentdata.size() > 0)
{
mav.addObject("PageHeading","Academic Year:"+request.getParameter("ac_year")+" School: "+request.getParameter("school"));
mav.addObject("studentdata",studentdata);
mav.addObject("schooltype",request.getParameter("school").split("-")[2]);
request.setAttribute("school",request.getParameter("school"));
}
else
{
mav.addObject("msg","All Applications are Confirmed");
mav.addObject("showyear","showyear");
}
mav.setViewName("studentstatusedit");
return mav;
}
Though I have added sessionAttribute i get ac_year as null in next method.
Please Tell me where im being wrong

First you need to initialize ModelAttribute and use the ModelAttribute name in the method parameter
#Controller
#SessionAttributes("basschoolsform")
public class SchoolStudentsConfirmationContrl
{
#ModelAttribute("basschoolsform")
public BASSchoolsForm populate(){
return new BASSchoolsForm();
}
................
public ModelAndView ConfirmStudentByDO(#ModelAttribute("basschoolsform") BASSchoolsForm basschoolsform,HttpServletRequest request)
{

Related

How spring mvc handle responsebody and view excpetion?

I have a controller as
#Controller
#RequestMapping("/test")
public class TestController {
#RequestMapping("/1")
#ResponseBody
public String test1(){
Object o = null;
o.toString();
return "I ma test one!";
}
#RequestMapping("/2")
public String test2(){
Object o = null;
o.toString();
return "test";
}
}
Is it possible to create ControllerAdvice(s) to handle the controller method as different result without moving these to message to different classes.
I mean:
1. test1 returns a String message: if there is exception, handle it with handleError1 and return a message.
2. test1 returns a view : if there is exception, handle it with handleError2 and return/redirect to a view.
#ControllerAdvice
public class AdviceController {
#ExceptionHandler({ NullPointerException.class })
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public Map handleError1(IllegalStateException ex, HttpServletRequest request) {
Map map = new HashMap();
map.put("code","1000");
map.put("message","NullPointerException of Object");
return map;
}
#ExceptionHandler(NullPointerException.class)
#ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public String handleError2(MultipartException e, RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("message", e.getCause().getMessage());
redirectAttributes.addFlashAttribute("code", "1000");
return "redirect:/error";
}
}
if use
#ControllerAdvice(annotations=RestController.class)
#ControllerAdvice(annotations=Controller.class)
We need to create more controllers.

SpringMVC - Method can return a Redirect (String) or a ModelAndView

My method makes a decision; in one case it redirects to a URL. In another case, it has to do a ModelAndView JSP refresh.
What should be the signature of this method?
Right now,
public String removeForm(final HttpServletRequest request) throws Exception
{
if (condition1) {
return "redirect:/myaction";
}
else {
// Need to do a View, or a ModelAndView?
}
}
Conversely, my method could be a ModelAndView-based method, but I'd need to return a Redirect string in one case. How to combine them?
the most easy way is to just use Object for return type.
public Object removeForm(final HttpServletRequest request) throws Exception
{
if (condition1) {
return "redirect:/myaction";
} else {
return new ModelAndView("jspName", modelMap);
}
}
but the more elegant is to use ModelAndView and use the RedirectView in redirect case
public ModelAndView removeForm(final HttpServletRequest request) throws Exception
{
if (condition1) {
return new ModelAndView(new RedirectView("/myaction"));
} else {
return new ModelAndView("jspName", modelMap);
)
}
If you need to return always a String ,you can use the Model class in your method and return the view name as String, it works like you return a ModelAndView:
public String removeForm(final HttpServletRequest request, Model model)throws Exception
{
if (condition1) {
return "redirect:/myaction";
}else {
model.addAtribute("objectName",object);
return "viewName";
}
}

No session to write JSON lazy load

I'm just starting with spring and hibernate. I'm trying to create some basic service using DAO.
Here is one of it:
#SuppressWarnings("unchecked")
#Override
public Users findByUserId(int id) {
List<Users> users = new ArrayList<Users>();
if(getSessionFactory() != null) {
try {
session = getSessionFactory().getCurrentSession();
users = session
.createQuery("from Users where id=?")
.setParameter(0, id)
.list();
} catch (HibernateException e) {
LOGGER.error("HibernateException: " + e);
}
}
if (!users.isEmpty()) {
return users.get(0);
} else {
return null;
}
}
And I called this service from a controller:
#RestController
public class JSONController {
#Autowired
private UserDao userDao;
#RequestMapping(value = "/rest/userbyid/{id}",
method = RequestMethod.GET,
headers = "Accept=application/json")
public Users getUserById(#PathVariable("id") int id) {
return userDao.findByUserId(id);
}
}
I understand that the session had been closed when the process come to controller. I can solve this by using openSession() method.
I just want to know is there any better way to handle this? Better still using getCurrentSession() (or any).
It's not good to return Entity to be serialized in controller. Imagine serializer which invokes all methods and even lazy collections.
For User instance it calls let's say getProjects() lazy method, then for each Project returned it agains call getUser() and so on.
Good practice is to define Service layer and return DTO (Data Transfer Object) which contains only necessary fields.
There is alternative approach to unproxy entities before return defining depth.
#SuppressWarnings("unchecked")
protected T unproxy(T entity){
if (entity == null) {
return null;
}
if (entity instanceof HibernateProxy) {
try {
Hibernate.initialize(entity);
} catch (ObjectNotFoundException e) {
return null;
}
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return entity;
}
From
https://gist.github.com/maikelsperandio/6889130

Why is Spring not running my Validator?

I am using Spring MVC and I am making a Validator but it looks like Spring is never running it.
Here is my Validator is a easy one right now just checking for two fields
public class MemberRequestValidator implements Validator {
public boolean supports(Class aClass) {
return MemberRequest.class.equals(aClass);
}
public void validate(Object obj, Errors errors) {
MemberRequest mr = (MemberRequest) obj;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "content", "Content field is Required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "areacode", "Area code field is Required");
}
}
Now my controller looks like the following:
#InitBinder("memberrequest")
public void initMemberRequestBinder(WebDataBinder binder) {
binder.setValidator(new MemberRequestValidator());
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView saveRequest(#ModelAttribute #Valid MemberRequest mr, BindingResult result)
{
if (result.hasErrors())
{
LOGGER.debug("Pages had errors on it... returning to input page");
return new ModelAndView("question");
}
else
{
String Ticket = mService.sentWebRequest(mr);
Map<String, Object> model = new HashMap<String, Object>();
Ticket t = new Ticket();
t.setTicketDetails(Ticket);
model.put("ticket", t);
return new ModelAndView("thanks", model);
}
}
and in my JSP page I have the following:
<c:url var="saveUrl" value="/mrequest/save.html" />
<form:form modelAttribute="memberrequest" action="${saveUrl}" name="memberrequest" id="memberrequest">
so if I dont enter any data in on the form I should hit the errors but I dont?
Try with #ModelAttribute("memberrequest") in handler or modelAttribute="memberRequest" in form and #initBinder("memberRequest")

Spring MVC ExceptionHandling: action annotated as #ExceptionHandling can't pass variable to error view

I know a lot of people have had issues similar to this.Sorry posting it again, but i believe there is something i might not be doing well.
I'm using Spring 3.0.5 with freemarker 2.3.14. Basically i wanted to show a friendly error message to the user.
#Controller("exceptioncontroller")
public class ExceptionController {
private static Logger logger = Logger.getLogger(ExceptionController.class);
#RequestMapping(value = "/site/contentnofoundexception")
public String throwContentFileNotFound(){
boolean exception = true;
if(exception){
throw new ContentFileNotFoundException("content ZZZ123 not found");
}
return "errortest";
}
#ExceptionHandler(value = ContentFileNotFoundException.class)
public String handleFileNotFoundException(ContentFileNotFoundException ex, Model model) {
model.addAttribute("msg",ex.getErrorMessage());//this message is never passed to the error view. msg is always null
return "error";
}
}
//same issue for handleException action which uses ModelAndView
#ExceptionHandler(value = Exception.class)
public ModelAndView handleException(Exception ex){
logger.error(ex);
ModelAndView mv = new ModelAndView();
mv.setViewName("error");
String message = "Something Broke. Please try again later";
mv.addObject("msg", message);
return mv;
}
// Custom Exception class
public class ContentFileNotFoundException extends RuntimeException {
private String errorMessage;
public ContentFileNotFoundException(String message) {
this.setErrorMessage(message);
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
So each case either handleFileNotFoundException or handleException actions are called alright but they can't send any message to the error.ftl view to display to the user. Is there anything i need to configure?
Thanks for helping in advance

Resources