SpringMVC forwards to wrong view name - spring-mvc

I have created a method which returns a ModelAndView in order to display a list with a jsp "resourcelist". It executes the method showResourceList() but after the return, I get a 404 error on /WEB-INF/views/resources.jsp.
"The resource requested is not found".
But in my views, there is no jsp named resources.jsp. I don't understand why it tries to find this view which doesn't exist. As you can see in my controller's code, I'm trying to forward to resourcelist.jsp and not to resources.jsp.
I've many other controllers returning a ModelAndView which work just fine.
Can anybody help me ?
Here’s the code :
package learningresourcefinder.controller;
import java.util.List;
import learningresourcefinder.model.Resource;
import learningresourcefinder.repository.ResourceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.portlet.ModelAndView;
#Controller
public class RessourceListController extends BaseController<Resource>{
#Autowired ResourceRepository resourcerepository;
#RequestMapping("/resources")
public ModelAndView showResourceList () {
List<Resource> list=resourcerepository.findAllRessourceOrderByTitle();
return new ModelAndView("resourcelist", "resourceList", list);
}
}
Many thanks!
Sébastien.

Have you tried putting #RequestMapping("/resources") after the #Controller annotation and then have a String of the correct mapping/view as the return value in the showResourceList() method. So, for example:
#Controller
#RequestMapping("/resources")
public class RessourceListController extends BaseController<Resource>{
...
#RequestMapping(method = RequestMethod.GET)
public String showResourcesList(ModelMap model) {
// retrieve the list instance
model.addAttribute("resourcesList", list);
return "/resources/resourceslist";
}
...
}
Also, how is your viewResolver bean configured in your Spring configuration?

i've compared with another classes and i've seen i've done a wrong import. I had imported "springframework.web.servlet.Modelandview" instead importing "springframework.web.portlet.Modelandview".
Sorry...

Related

Micronaut multiple JDBC templates not working

I am trying to write a micronaut function which is deploying as AWS Lambda.
With my micronaut function, I need to connect to multiple databases and get the data and put details into AWS SQS. In this regard, I am trying to use JDBC template approach to get data from different data sources. But I am getting error: Multiple possible bean candidates found: [org.springframework.jdbc.core.JdbcTemplate, org.springframework.jdbc.core.JdbcTemplate, org.springframework.jdbc.core.JdbcTemplate] error
package io.test.invoice;
import io.micronaut.context.annotation.Factory;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.sql.DataSource;
#Factory
public class JdbcTemplateFactory {
#Singleton
JdbcTemplate jdbcTemplateOne(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
#Singleton
JdbcTemplate jdbcTemplateTwo(#Named(value = "database2") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
package io.test.invoice;
import io.micronaut.context.annotation.Requires;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.inject.Singleton;
import java.util.List;
#Singleton
#Requires(beans = JdbcTemplate.class)
public class CodeSetRepository {
private final JdbcTemplate jdbcTemplateOne;
private final JdbcTemplate jdbcTemplateTwo;
public CodeSetRepository(JdbcTemplate jdbcTemplateOne, JdbcTemplate jdbcTemplateTwo) {
this.jdbcTemplateOne = jdbcTemplateOne;
this.jdbcTemplateTwo = jdbcTemplateTwo;
}
public List<CodeSet> getAllCodeSets() {
String SELECT_QUERY = "SELECT * FROM public.code_set";
return this.jdbcTemplateTwo.query(SELECT_QUERY, new BeanPropertyRowMapper(CodeSet.class));
}
public List<Country> getAllCountries() {
String SELECT_QUERY = "SELECT * FROM public.country";
return this.jdbcTemplateOne.query(SELECT_QUERY, new BeanPropertyRowMapper(Country.class));
}
}
Could anyone help with this please?
The name of the parameter jdbcTemplateOne has no bearing on the injection. So both parameters are asking for the same thing. There are multiple templates thus Micronaut doesn't know which one to inject.
In your factory you can create a template for each datasource with
#EachBean(DataSource.class)
JdbcTemplate jdbcTemplateOne(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
Then the named qualifier of the datasource will transfer to the template. That means in your example you could inject #Named("database2") JdbcTemplate jdbcTemplate.
Alternatively you can add #Named qualifiers to the factory methods and then inject the jdbc templates with those qualifiers.
Change your repository constructor like below
#Inject
public CodeSetRepository(#Named("database2") JdbcTemplate jdbcTemplateOne) {
this.jdbcTemplateOne = jdbcTemplateOne;
}

SpringMVC-Aspectj integration

I want to configure spring AOP into my Spring MVC project:
Below is the code:
package com.samik.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.web.servlet.ModelAndView;
#Aspect
public class LoggingAspect {
#Before("HomeGetter()")
public void LoggingAdvice(JoinPoint joinPoint){
System.out.println("Logger Advice called for Home Request");
System.out.println(joinPoint.toString());
}
#Pointcut("execution(protected ModelAndView getHomePage())")
public void HomeGetter(){}
}
-------------------------------------------------------------------------
Main.java
#RequestMapping(value="/Home.html", method = RequestMethod.GET)
protected ModelAndView getHomePage(){
ModelAndView modelAndView = new ModelAndView("content/home/Home");
return modelAndView;
}
Added the below code in dispatcher servlet:
<bean id = "loggingAspect" class = "com.samik.aspect.LoggingAspect" />
<aop:aspectj-autoproxy>
<aop:include name='loggingAspect' />
</aop:aspectj-autoproxy>
Not getting the error, Please help. Looked into the internet, this is what the solution is proposed.
Please revert if i am missing anything?
The error message ModelAndView [Xlint:invalidAbsoluteTypeName] means that in your pointcut you use a type name which does not exist (or is not fully qualified). It should help to change the pointcut to:
#Pointcut("execution(protected org.springframework.web.servlet.ModelAndView getHomePage())")

Map<string,string> variable is not getting added in DynamoDB Local but works well in Real DynamoDB

I am trying to add Map variable using Spring for DynamoDb plugin into DynamoDbLocal database .... It doesnt give any error when I write but when I read the same variable I get a null value against the map request.
This datatype is by default managed by DynamoDbMapper I believe. Do you have any idea what wrong or what needs to be done ?
Here's my domain code
package com.wt.domain;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.annotation.Id;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#DynamoDBTable(tableName = "Notification")
#AllArgsConstructor
#NoArgsConstructor
public class Notification implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#DynamoDBIgnore
private NotificationCompositeKey notificationCompositeKey = new NotificationCompositeKey();
#Getter
#Setter
#DynamoDBAttribute // This is the Map - Giving Null when read
private Map<String,String> jsonMessage = new HashMap<String, String>();
#DynamoDBHashKey(attributeName = "identityId")
public String getIdentityId() {
return notificationCompositeKey.getIdentityId();
}
public void setIdentityId(String identityId) {
notificationCompositeKey.setIdentityId(identityId);
}
public void setTimestamp(long timestamp) {
notificationCompositeKey.setTimestamp(timestamp);
}
#DynamoDBRangeKey(attributeName = "notificationTimestamp")
public long getTimestamp() {
return notificationCompositeKey.getTimestamp();
}
}
Firstly, I presume that you have tested the code connecting to real DynamoDB on some deployed environment rather than on local.
I think, the problem is not on local DynamoDB. The problem should be the way you create getter and setter using lombok API. If you remove the lombok getter and setter annotation and add the getter/setter manually. It should work on local Dynamodb as well. I have seen this behavior.
#DynamoDBAttribute(attributeName = "jsonMessage")
public Map<String, String> getJsonMessage() {
return jsonMessage;
}
public void setJsonMessage(Map<String, String> jsonMessage) {
this.jsonMessage = jsonMessage;
}
Thanx guys - The issue got resolved and the problem was that I kept a condition if the value is null then insert blank string for that key-value in the map.
Even as per the AWS Documentation - it wont allow the Map or the List Datatype to be entered if the value is null or blank.

JSON support in Global Exception Handler Spring MVC Rest controller

I am creating a global exception handler in spring mvc application with rest controller.
From controller when I am throwing Exception, the global exception handler catches it, but it is not returning the json data. But when I am using the #ExceptionHandler in the controller, it returns json data.
controller code:
import javax.validation.Valid;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.sphiextest1back.bean.NewUserBean;
import com.sphiextest1back.bean.ResponseBean;
import com.sphiextest1back.exception.FieldValidationException;
#RestController
#RequestMapping(value = "/service")
public class User {
#RequestMapping(value = "/test/test", method = RequestMethod.GET)
public ResponseBean testFunc(#Valid NewUserBean newUserBean, BindingResult result) throws FieldValidationException {
ResponseBean responseBean = new ResponseBean();
if(result.hasErrors()) {
throw new FieldValidationException("Error in field values", responseBean);
}
else {
responseBean.setMessage("Test Message1");
responseBean.setSuccess(true);
responseBean.setStatusCode(200);
}
return responseBean;
}
/**This Works fine when uncommented**/
/*#ExceptionHandler(FieldValidationException.class)
#ResponseBody
public ResponseBean handleFieldValidationException(Exception ex) {
ResponseBean responseBean = new ResponseBean();
responseBean.setStatusCode(401);
responseBean.setMessage(ex.getMessage());
responseBean.setSuccess(false);
return responseBean;
}*/
}
But when using global exception handler, it is not returning json data rather showing HTTP error page with status 500.
Here is my global exception handler code.
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.sphiextest1back.bean.ResponseBean;
#ControllerAdvice
public class GlobalExceptionHandler {
/**
* Method handles the FieldValidationException
*
* #param ex
* #return responseBean
*/
#ExceptionHandler(FieldValidationException.class)
public #ResponseBody ResponseBean handleFieldValidationException(Exception ex) {
ResponseBean responseBean = new ResponseBean();
responseBean.setStatusCode(401);
responseBean.setMessage(ex.getMessage());
responseBean.setSuccess(false);
return responseBean;
}
}
Is there any way to return json data from ResponseBean object!!
It was my mistake. In the xml file I did not include the global exception package for
Now I included the package and it is working fine.

Spring MVC: How to get view-name in JSP?

Is a way to access view name in JSP (profile in example below) or i need to add this name to model ?
#RequestMapping(value="/user/account", method=RequestMethod.GET)
return "profile";
}
I ran into this same problem recently. There could be an official way to solve this problem, but I couldn't find it. My solution was to create an interceptor to place the view name into the model.
My interceptor is very simple:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class ViewNameInModelInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null) {
modelAndView.addObject("springViewName", modelAndView.getViewName());
}
super.postHandle(request, response, handler, modelAndView);
}
}
And registering it in the spring config, is also pretty simple (using the namespace configuration):
<mvc:interceptors>
<beans:bean class="ViewNameInModelInterceptor" />
</mvc:interceptors>
${requestScope['javax.servlet.forward.servlet_path']}
Just for people that will search for Thymeleaf solution:
${#httpServletRequest.getServletPath()}
You can get a view name in the jsp page as it shown below:
${pageContext.request.servletPath}

Resources