Why can't my Spring MVC controller mapping reference another mapping in the same controller? - spring

I have the following controller mapped as
#Controller( value = "stockToStoreController" )
#RequestMapping("/stsr")
public class StockToStoreController extends BaseController {...}
I have a delete mapping
#Transactional(propagation = Propagation.REQUIRED)
#RequestMapping(value = "/delete")
public String delete(#RequestParam("xxxId") long xxxId) {
XXXModel xxxModel = stockToStoreDao.findById(xxxId);
if(xxxModel != null) {
xxxDao.delete(xxxModel);
}
return "/stsr/requery";
}
That mapping looks like this
#SuppressWarnings("unchecked")
#RequestMapping(value = "/requery")
public ModelAndView requery(HttpServletRequest request) {
ModelAndView mav = new ModelAndView("manageStockToStore");
//do stuff
return mav;
}
I try to call another mapping in the return ie., return "/stsr/requery"; I get
the following error:
Uncaught exception thrown in one of the service methods of the servlet: mptstp. Exception thrown : javax.servlet.ServletException: Could not resolve view with name '/stsr/requery' in servlet with name 'xxx'
Question is, do I need to explicitly define this mapping somewhere? I do not have any MappingHandlers defined and my -servlet.xml looks like
<!-- Configures the #Configuration annotation for java configuration -->
<context:annotation-config/>
<!-- Scans the classpath of this application for #Components to deploy as beans -->
<context:component-scan base-package="xxx.testspringmvc.stsr" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Configures resources so they can be used across web modules -->
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/public-resources/" />
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="classpath:META-INF/public-resources/mptstp-messages, classpath:META-INF/public-resources/mptstp-error-messages, classpath:META-INF/public-resources/stsr/stsr-messages" />
<property name="cacheSeconds" value="0" />
</bean>
<!-- Spring MVC View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="stsr-views" />
<property name="defaultParentView" value="parentView"/>
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="urlConfiguredSiteIdInterceptor" class="xxx.testspringmvc.stsr.interceptor.UrlConfiguredSiteIdInterceptor">
<property name="siteIdConfigParamName" value="urlConfiguredSiteId" />
<property name="errorView" value="siteIdNotFound" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
Any help from you guys would be greatly appreciated.

Two options:
you can redirect return "redirect:/stsr/requery"
you can directly invoke the other method: return requery(request);

It's looking for a view and you want a mapping. You have to use a redirect:
return "redirect:/stsr/requery";

Related

Spring configuration split between xml resource and Java configuration

I am trying to mix both xml and Java Configuration.
I have a spring-security.xml resource that I import in my application boot.
Say this was a part of the initial xml:
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.user}" />
<property name="password" value="${ldap.password}" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="ldapContextSource" />
</bean>
Can I move just this part to be a Java config ? Or would the references be an issue.
Thank You
You can move it to Java Config
Declare configuration class
#Configuration
public class AppConfig {
#Bean
public LdapContextSource ldapContextSource(){
LdapContextSource lcontext = new LdapContextSource();
lcontext.setUrl("${ldap.url}");
lcontext.setBase("${ldap.base}");
lcontext.setUserDn("${ldap.user}");
lcontext.setPassword("${ldap.password}");
return lcontext;
}
#Bean
public LdapTemplate LdapTemplate(){
LdapTemplate lTemplate = new LdapTemplate(ldapContextSource());
return lTemplate;
}
}
In your XML add
<context:annotation-config/>
<bean class="com.mypackage.AppConfig"/>

indexing document to a specific collection using spring data solr

I am trying to index a document to a specific collection in solr. The collection name is 'program'. I am using spring data solr.
I am getting the below error when trying to save the document:
HTTP ERROR 404
Problem accessing /solr/update.
Reason:Not Found
My assumption is that the annotation #SolrDocument is not recognized. spring-data-solr is trying to post the document to /solr/update whereas it should try to post it to /solr/program/update.However I am not sure how to prove it or fix it.
My schema is available on the link below:
http://<solr-host>/solr/program/schema
The update request handler is available in the link below:
http://<solr-host>/solr/program/update
spring-config-xml
<context:annotation-config />
<context:component-scan base-package="com.oostnet.controllers, com.oostnet.models, com.oostnet.services" />
<mvc:annotation-driven />
<solr:solr-server id="solrServer" url="http://<solr-host>/solr" />
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer" />
</bean>
<solr:repositories base-package="com.oostnet.solr.repositories" />
Model definition:
package com.oostnet.models.documents;
#SolrDocument(solrCoreName="program")
public class Program {
#Id
#Indexed
private String id;
<more variables>
}
Repository definition:
package com.oostnet.solr.repositories;
public interface ProgramRepository extends SolrCrudRepository<Program, String> {
}
Controller:
package com.oostnet.controllers;
public class ProgramController{
private ProgramRepository programRepository;
#Autowired
public void setProgramRepository(ProgramRepository programRepository) {
this.programRepository = programRepository;
}
public void createProgram(Program program) {
programRepository.save(program);
}
}
Below are the versions used:
<spring.data.solr.version>1.3.2.RELEASE</spring.data.solr.version>
<spring.version>4.1.4.RELEASE</spring.version>
solr server version - solr-spec 4.10.2
To work on multiple collection you need to enable multiple repository under spring configuration as below :-
<context:annotation-config />
<context:component-scan base-package="com.test.solr" />
<solr:solr-server id="solrServer" url="http://localhost:8983/solr" />
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServerFactory" />
</bean>
<solr:repositories base-package="com.test.solr.repositories" multicore-support="true" />
<bean id="solrServerFactory"
class="org.springframework.data.solr.server.support.MulticoreSolrServerFactory">
<constructor-arg ref="solrServer" />
<constructor-arg name="cores">
<list>
<value>program</value>
</list>
</constructor-arg>
</bean>

How to set map(master) values to bean in Spring? How to show in jsp?

I had stored in map for context-param values from web.xml at startup tomcat server time.
I want store map values to bean and populate jsp.
Thanks in Advance
Based on your comments, it looks as though you just need to expose the map on the model. Use a method annotated with #ModelAttribute in your controller, not #RequestMapping:
#Controller
public class YourController {
#Autowired
private ServletContext context;
#ModelAttribute("staticValues")
public Map<String, String> getStaticValues() {
Map<String, String> map = new HashMap<String, String>();
map.put("test1",context.getInitParameter("test1"));
map.put("test2",context.getInitParameter("test2"));
map.put("test3",context.getInitParameter("test3"));
map.put("test4",context.getInitParameter("test4"));
return map;
}
...
}
And then in the jsp you can do:
<c:out value="${staticValues.test1}" />
<c:out value="${staticValues.test2}" />
<c:out value="${staticValues.test3}" />
...etc...
One way of achieving this would be to set classA up in your Spring configuration with the appropriate property config:
<bean id="classA" class="some.package.ClassA">
<property name="propName" value="propValue"/>
...etc...
</bean>
You could then expose this in the view resolver configuration using the exposeContextBeansAsAttributes property:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
And then in any jsp, you could access the properties of the classA bean directly:
<c:out value="${classA.propName}"/>

Bean creation exception in spring mobile

I am getting the following exception while using sample
nested exception is
org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.mobile.device.Device]: Specified class is an interface] with root cause
My controller is as follows:
package com.srccodes.spring.controller;
import java.util.logging.Logger;
import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.site.SitePreference;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* #author Abhijit Ghosh
* #version 1.0
*/
#Controller
public class SpringMobileHelloController {
private static final Logger logger = Logger.getLogger(SpringMobileHelloController.class.getName());
#RequestMapping("/")
public String sayHello(SitePreference sitePreference, Device device, Model model) {
logger.info("SitePreference : " + sitePreference);
logger.info("Device : " + device);
model.addAttribute("message", "Hello World!");
return "helloWorld";
}
}
My dispatcher-servlet.xml is:
(some parts omitted)
<context:component-scan base-package="com.srccodes.spring.controller" />
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.site.SitePreferenceWebArgumentResolver" />
<bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:interceptors>
<!-- Resolve the device which has generated the request -->
<bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
<!-- User's site preference -->
<bean class="org.springframework.mobile.device.site.SitePreferenceHandlerInterceptor" />
<!-- Redirects users to the device specific site -->
<bean class="org.springframework.mobile.device.switcher.SiteSwitcherHandlerInterceptor" factory-method="urlPath">
<constructor-arg value="/m" />
<constructor-arg value="/t" />
<constructor-arg value="/SpringMobileHelloWorld" />
</bean>
</mvc:interceptors>
<!-- Device aware view resolving -->
<bean id="liteDeviceDelegatingViewResolver" class="org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver">
<constructor-arg>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
</constructor-arg>
<property name="mobilePrefix" value="m/" />
<property name="tabletPrefix" value="t/" />
<property name="enableFallback" value="true" />
</bean>
</beans>
Please help me out as I am a beginner in spring mobile.This example is available in spring source official website.It is saying that device is a interface but I have used its implementing classes only.Basically I think its an error in dispatcher servlet.xml
Try to use Device filter:
<filter>
<filter-name>deviceResolverRequestFilter</filter-name>
<filter-class>org.springframework.mobile.device.DeviceResolverRequestFilter</filter-class>
</filter>
Anyway, you can retrieve the device from DeviceUtils, using an HttpServletRequest, like this handler example..:
public boolean preHandle(HttpServletRequest request, HttpServletResponse arg1, Object arg2) throws Exception {
Device device = DeviceUtils.getCurrentDevice(request);
...
}
I have the same problem and solve it with the second approach.
Check if <mvc:annotation-driven/> is not defined anywhere else.
Simply add:
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
<bean class="org.springframework.mobile.device.site.SitePreferenceWebArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
In addition to leogps answer, following is the Java Config
#Bean
public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() {
return new DeviceHandlerMethodArgumentResolver();
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(deviceHandlerMethodArgumentResolver());
}
You have to add argument resolver for this.
Follow this
If you'd like to pass the current Device as an argument to one of your #Controller methods, configure a DeviceWebArgumentResolver:
<annotation-driven>
<argument-resolvers>
<bean class="org.springframework.mobile.device.DeviceWebArgumentResolver" />
</argument-resolvers>
</annotation-driven>
You can alternatively configure a DeviceHandlerMethodArgumentResolver using Java-based configuration:
#Bean
public DeviceHandlerMethodArgumentResolver deviceHandlerMethodArgumentResolver() {
return new DeviceHandlerMethodArgumentResolver();
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(deviceHandlerMethodArgumentResolver());
}

Spring: SimpleMappingExceptionResolver together with #ExceptionHandler?

I like SimpleMappingExceptionResolver, because in one place i have all exception->view mappings for all controllers in web-app (i suppose that). To customize some exception in specific controller i would like to use #ExceptionHandler, but it doesn't work together - all exceptions are handled by SimpleMappingExceptionResolver. How to make this work together ?
#Controller
public class SomeController {
...
#ExceptionHandler(SomeException.class)
public ModelAndView handleException(Exception ex) {
// ...
}
}
SimpleMappingExceptionResolver:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="exceptionMappings">
...
</property>
</bean>
Short answer: p:order
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver" p:order="1" />
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:order="2" p:defaultErrorView="uncaughtException"/>
Full story: springsource forum.

Resources