I have multilanguage installed on my spring app, and I don't want the 'lang' parameter to appear in the URL (I'm storing the locale with sessionLocaleResolver or cookieLocaleResolver/neither works).
I've searched for hours to find a solution to this issue, although apparently it should already be working with what I've done. Here's my code :
The view (welcome.jsp) :
Language : English|Francais|Romanian
<h2>welcome.springmvc : <spring:message code="welcome.text" text="default text" /></h2>
My servlet.xml
<!-- Multi-Language / Localization Setup -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
<mvc:annotation-driven ignore-default-model-on-redirect="true" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:lang.files/welcome</value>
<!-- <value>classpath:messages2</value> -->
</list>
</property>
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
<property name="cookieName" value="lang" />
<property name="cookieMaxAge" value="60000" />
<property name="cookiePath" value="/" />
</bean>
My Controller code - note that I'm staying in the same page when I click on the link to change the language. Because ideally it would be a dropdown, and I'd stay in the same page
#RequestMapping("/welcome")
public ModelAndView helloWorld() {
String message = "<br/ ><div style='text-align:center;'>"
+ "<h3>********** Hello World, Spring MVC Tutorial</h3></div><br />";
ModelAndView mv = new ModelAndView();
// ModelAndView mv = new ModelAndView(new
// RedirectView("welcome.do", true, true, true));
RedirectView view = new RedirectView("/welcome", true);
view.setExposeModelAttributes(false);
mv.setView(view);
mv.addObject("message", message);
mv.addObject("activities", activityService.getAll());
mv.addObject("act", activityService.getR());
return new ModelAndView(view);
}
The result is a '404' saying that 'localhost/myapp/welcome' is not found.
Finally this the controller, working, but adding the 'lang' parameter in the URL :
#RequestMapping("/welcome")
public ModelAndView helloWorld() {
String message = "<br/ ><div style='text-align:center;'>"
+ "<h3>********** Hello World, Spring MVC Tutorial</h3></div><br />";
ModelAndView mv = new ModelAndView();
mv.addObject("message", message);
mv.addObject("activities", activityService.getAll());
mv.addObject("act", activityService.getR());
return mv;
}
Please help.
Thanks :)
#RequestMapping("/welcome")
public ModelAndView helloWorld() {
String message = "<br/ ><div style='text-align:center;'>"
+ "<h3>********** Hello World, Spring MVC Tutorial</h3></div><br />";
ModelAndView mv = new ModelAndView();
// ModelAndView mv = new ModelAndView(new
// RedirectView("welcome.do", true, true, true));
RedirectView view = new RedirectView("/welcome", true);
view.setExposeModelAttributes(false);
mv.setView(view);
mv.addObject("message", message);
mv.addObject("activities", activityService.getAll());
mv.addObject("act", activityService.getR());
return new ModelAndView(view);
}
This code causes an infinite loop as you are redirecting to /welcome over and over again.
Moreover when you've got a link like English the parameter will always appear in the url when you click on it.
The easiest way(not best) to achieve the goal you want is to create another controller method like
#RequestMapping("/changeLocale")
public ModelAndView changeLocale() {
RedirectView redirectView = new RedirectView("/welcome");
redirectView.setExposePathVariables(false);
return new ModelAndView(redirectView);
}
And links will look like
English|Francais|Romanian
Related
I need help with JasperReports and Spring MVC. I can export everything, but I can't set the filename in the output PDF/Excel that my software exports.
In my dispatcher-servlet I have this bean :
<!-- ViewResolver JasperReports -->
<bean id="jasperViewResolver" class="org.springframework.web.servlet.view.jasperreports.JasperReportsViewResolver">
<property name="prefix" value="classpath:/jasper/" />
<property name="reportDataKey" value="dataSource" />
<property name="suffix" value=".jrxml" />
<property name="viewNames" value="Report_*" />
<property name="viewClass">
<value>org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView</value>
</property>
<property name="order" value="1" />
</bean>
That is the ViewResolver provided by Spring MVC.
I have a function in my BaseController ( abstract controller extended by all the #Controller ) :
protected String exportReport(String reportName, String formatoReport, Model model, JRDataSource dataSource) {
model.addAttribute("dataSource", dataSource);
model.addAttribute("format", formatoReport);
return reportName;
}
So, what I do is simply returning this view name from all my #RequestMapping :
#RequestMapping(..something)
public String functionName(...something else) {
.. do some stuff
return exportReport("Report_docIngresso", EFormatoReport.XLS, model, jrDataSource);
}
This works. The export is perfect, but I didn't find the way to set the filename of the exported pdf/excel, that comes out like the latest part of the URL I called before exporting the report.
I already tried to set in the HttpServletResponse the content-disposition with the filename, but it didn't work.
Thanks a lot,
Marco
Try setting the Content-Disposition HTTP response header:
#RequestMapping(..something)
public String functionName(HttpServletResponse response, ...something else) {
.. do some stuff
String header = "inline; filename=myfile.xls";
response.setHeader("Content-Disposition", header);
return exportReport("Report_docIngresso", EFormatoReport.XLS, model, jrDataSource);
}
(Note I saw just now your concluding comment that you tried without success to set the content disposition header. Well.. I can only say it worked for me in a similar setup.)
First, I execute save.do in edit.jsp
#RequestMapping(value = "/saveUser.do")
public String saveUser(User user) {
userService.save(user);
return "redirect:/listUser.do";
}
I then system redirect to list.do
#RequestMapping(value = "/listUser.do")
public String listUser(User user, HttpServletRequest request) throws Exception {
List<User> list = userService.getAll(user, getRowBounds(request));
request.setAttribute("list", list);
return "/framework/system/user/listUser";
}
When I use chrome, the page will view new data.
But if I use IE7, the page does not view new data, only views the old data.
But with IE11 seems to be working fine.
Tanks for every one.
I find the answer.
Add
<mvc:interceptors>
<bean id="webContentInterceptor"
class="org.springframework.web.servlet.mvc.WebContentInterceptor">
<property name="cacheSeconds" value="0"/>
<property name="useExpiresHeader" value="true"/>
<property name="useCacheControlHeader" value="true"/>
<property name="useCacheControlNoStore" value="true"/>
</bean>
</mvc:interceptors>
how to set header no cache in spring mvc 3 by annotation
I have a product page which displays all products
home.jsp:
<a class="campaign" href="page/dynamic/product1">
Controller
#RequestMapping(value="/page/dynamic/{pagename}")
public ModelAndView loadProductPage(ModelMap model, #PathVariable("pagename") String pagename) {
model.addAttribute("productname",pagename);
return new ModelAndView("products/"+pagename+"/"+pagename);
}
It is getting redirected to the product1 page. Product1 page has a link called features
product1.jsp
<li>Features</li>
Controller
#RequestMapping(value="/page/loadpage/{choosedProduct}/{linkChoosed}")
public ModelAndView loadProductMenuPages(ModelMap model, #PathVariable("linkChoosed") String linkChoosed, #PathVariable("choosedProduct") String choosedProduct) {
System.out.println("Loading links here");
System.out.println("cones gere");
System.out.println("Product Choosed" + choosedProduct);
System.out.println("Link Choosed" + linkChoosed);
return new ModelAndView("products/"+choosedProduct+"/"+linkChoosed);
}
It is not getting redirected to the "features page", but throws an error:
HTTP Status 404 - /controller/WEB-INF/views/products/loadpage/loadpage.jsp
What should I need to do to get redirected to features page?
EDIT:
Adding servlet-context.xml informed in comment:
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
In your configuration file please configure below tag
<bean id="PageRedirect"
class="org.springframework.web.servlet.view.RedirectView">
<property name="url" value="RedirectPage.jsp" />
</bean>
And in your controller
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView("PageRedirect");
}
Hi I am trying to authenticate the user but seems like its calling a jsp page instead of another controller mapping.
My dispatcher servlet is
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.beingjavaguys.domain.User</value>
<value>com.beingjavaguys.domain.Chat</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My web.xml is
dispatcher
org.springframework.web.servlet.DispatcherServlet
1
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
and my controller is
#RequestMapping(value="/authenticate",method=RequestMethod.POST)
public ModelAndView getAuthenticateResult(#ModelAttribute("user") User user,
BindingResult result) {
if(userService.authenticate(user))
{
return new ModelAndView("/userList");
}
else{
return new ModelAndView("Login");
}
}
#RequestMapping(value="/userList", method=RequestMethod.GET)
public ModelAndView getUserList() {
Map<String, Object> model = new HashMap<String, Object>();
model.put("chat", userService.getChat());
return new ModelAndView("UserDetails", model);
}
I am calling authenticate.html from my login file using POST method but my problem is this error
HTTP Status 404 - /Spring-hibernate-integration-helloworld/WEB-INF/view/userList.jsp
type Status report
message /Spring-hibernate-integration-helloworld/WEB-INF/view/userList.html.jsp
description The requested resource is not available.
Why is it searching for the jsp file instead of redirecting it to a controller method?
But if i use redirect:/userList.html it works then.Whats the logic behind it?
If you return a string that is interpreted as a name of a view to render. The name of the view is passed no the a ViewResolver (in your case probably an InternalResourceViewResolver) which will generate an (internal) URL to forward to. In this case that will be a JSP.
Now the redirect: and forward: prefixes are 2 special cases. The redirect: will result in a client side redirect to that URL, which in turn will call your controller due to your configuration. A forward: is handled on the server side and not the client side.
To be exact. The logic behind it is:
org.springframework.web.servlet.view.UrlBasedViewResolver
/**
* Overridden to implement check for "redirect:" prefix.
* <p>Not possible in {#code loadView}, since overridden
* {#code loadView} versions in subclasses might rely on the
* superclass always creating instances of the required view class.
* #see #loadView
* #see #requiredViewClass
*/
#Override
protected View createView(String viewName, Locale locale) throws Exception {
// If this resolver is not supposed to handle the given view,
// return null to pass on to the next resolver in the chain.
if (!canHandle(viewName, locale)) {
return null;
}
// Check for special "redirect:" prefix.
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
return applyLifecycleMethods(viewName, view);
}
// Check for special "forward:" prefix.
if (viewName.startsWith(FORWARD_URL_PREFIX)) {
String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
return new InternalResourceView(forwardUrl);
}
// Else fall back to superclass implementation: calling loadView.
return super.createView(viewName, locale);
}
I have a problem with method handler return value in spring mvc
I have a grid and when user click on a row I have to show the details of row.
I don't want to send row Id in URL,when I use #PathVariable everything work perfect
I used jqGrid in my jsp to get the Id of selected row
onSelectRow: function(id) {
document.location.href = "/customer/" + id;
}
my controller is :
#RequestMapping("/customer")
#Controller
public class CustomerController {
final Logger logger = LoggerFactory.getLogger(CustomerController.class);
#Autowired
private CustomerService customerService;
#Autowired
MessageSource messageSource;
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String show(Authentication authentication, #PathVariable("id") int id, Model uiModel, Locale locale) {
User user = (User) authentication.getPrincipal();
String result = null;
try {
if (user != null) {
if (user.getRole().getRoleType().equalsIgnoreCase("ADMIN")) {
Customer customer = customerService.getCustomerById(id);
uiModel.addAttribute("customer", customer);
result = "customer/show";
} else
result = "/customer/all";
}
} catch (Exception e) {
uiModel.addAttribute("message", new Message("error",
messageSource.getMessage("customer_get_all_fail", new Object[]{}, locale)));
e.getStackTrace();
}
return result;
}
my apache tiles config for load detail page:
<definition extends="default" name="customer/show">
<put-attribute name="body"
value="/WEB-INF/views/customer/showCustomerData.jspx" />
and my servelt-context.xml
<mvc:annotation-driven/>
<mvc:resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**"/>
<tx:annotation-driven/>
<context:annotation-config/>
<mvc:default-servlet-handler/>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</mvc:interceptors>
<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource"
p:basenames="WEB-INF/i18n/messages,WEB-INF/i18n/application" p:fallbackToSystemLocale="false"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<context:component-scan base-package="com.sefryek.sywf.web.controller"/>
<!-- Enable file upload functionality -->
<!--<bean class="org.springframework.web.multipart.support.StandardServletMultipartResolver" id="multipartResolver"/>-->
<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="10000000"/>
</bean>
<bean id="contentNegotiatingResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order"
value="#{T(org.springframework.core.Ordered).HIGHEST_PRECEDENCE}"/>
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="pdf" value="application/pdf"/>
<entry key="xsl" value="application/vnd.ms-excel"/>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
<entry key="js" value="application/javascript"/>
</map>
</property>
</bean>
<!--<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"-->
<!--p:prefix="/WEB-INF/views/" p:suffix=".jsp" p:order="#{contentNegotiatingResolver.order+0}"/>-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
p:cookieName="locale" p:cookieMaxAge="11"/>
<!-- Tiles Configuration -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layouts/layouts.xml</value>
<!-- Scan views directory for Tiles configurations -->
<value>/WEB-INF/views/**/views.xml</value>
</list>
</property>
</bean>
<bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver"
p:cookieName="theme" p:defaultThemeName="standard"/>
<bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"/>
</beans>
and anything work perfect,but I have to send my data in request object instead of in URL
my code
in jsp :
onSelectRow: function(id) {
$.ajax({
url : '${showSelectedCustomer}',
dataType: 'JSON',
data:{ id: id },
type:'POST',
success: function(response) {
} ,
error : function(r) {
}
});
}
and my method handler:
#RequestMapping(value = "/showSelectedCustomer", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
//#ResponseBody
public String showSelectedCustomer(
Authentication authentication,
#RequestParam String id,
Model uiModel, Locale locale) {
User user = (User) authentication.getPrincipal();
Customer customer = null;
Map<String, Object> map = new HashMap<String, Object>();
try {
if (user != null) {
if (user.getRole().getRoleType().equalsIgnoreCase("ADMIN")) {
customer = customerService.getCustomerById(Integer.valueOf(id));
uiModel.addAttribute("customer", customer);
}
}
} catch (Exception e) {
uiModel.addAttribute("message", new Message("error",
messageSource.getMessage("customer_get_all_fail", new Object[]{}, locale)));
e.getStackTrace();
}
return "customer/show";
}
my method handler is called but after that nothing is happened.
my point is showCustomerData.jspx that show a details of customer isn't loaded.
please let me know what should I do and what my problem is?
when I use my data with Ajax,how should I return my return value to see detail page (showCustomerData.jspx)
when I change my method handler to return a map with map.put("message", "success") data,my ajax success function is called but I don't know how can I redirect it to show my details page
thank you
You first need to create CustomerInput pojo like below
class CustomerInput{
private Integer id;
//setter getter
}
Then create controller method like below
#ResponseBody public String showSelectedCustomer( Authentication authentication, #RequestBody CustomerInput customerInput, Model uiModel, Locale locale) {
}