How to get requestURI by using jstl in spring mvc project? - spring

I google a lot and get a answer:
<c:out value="${pageContext.request.requestURI}" />
But I get /myapp/WEB-INF/views/index.jsp
I want to get /myapp/index
How can I do that?
My project is using spring mvc.
My config in spring-mvc.xml:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
In my /WEB-INF/views/, has a index.jsp
My Controler:
#RequestMapping("/index")
public String welcome() {
return "index";
}
When I view localhost:8088/myapp/index, It shows.

Try to use ${requestScope['javax.servlet.forward.servlet_path']}
javax.servlet.forward.* constants retrieve information based on URI passed to getRequestDispatcher() (DispatcherServlet sets this attribute while handling request in the case of Spring Web MVC). But it's independent of frameworks and web containers.
As documentation says FORWARD_SERVLET_PATH is:
The name of the request attribute under which the original servlet path is made available to the target of a forward
You should also remember that if the forward() works by calling getNamedDispatcher(), these attributes (there are 4 more similar attributes: request_uri, context_path, path_info and query_string) are not set because in this case the initial elements of the path does not change.

Related

Spring MVC:- how to redirect a user to some specific content pages in my application? [duplicate]

I have a Spring 2.5 application that contains a Flash banner. I don't have the source for the Flash component but it has links hardcoded to certain pages that end in .html I want to be able to redirect those .html pages to existing jsp pages. How can I have Spring resolve a few .html pages to .jsp pages?
My project looks like:
WebContent
|
-sample.jsp
-another.jsp
WEB-INF
|
-myapp-servlet.xml
-web.xml
I want localhost:8080/offers.html to redirect to localhost:8080/sample.jsp
Can I do this with Spring? I already have a SimpleUrlHandlerMapping and UrlFilenameViewController defined in the myapp-servlet.xml that has to continue serving the pages it already is.
In my web.xml, I have
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
Update
Here is the URL mapper. If I add a controller, how do I return the jsp view that is in the WebContent directory as the view resolver includes the /WEB-INF/jsp directory.
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/page1.htm">page1Controller</prop>
<prop key="/page2.htm">page2Controller</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
I think you could benefit from the open source URL Rewriting library made by tuckey.org. The guys at SpringSource endorse this library, since it is set up for you automatically if you use Spring Roo to create a project, so it is of good quality. I have used it successfully in a number of projects.
See here for its homepage. And Skaffman is right, you want it to 'forward' instead of redirect, which is the default behaviour.
Configure it in web.xml like this:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
Then, in WEB-INF/urlrewrite.xml have an element like this:
<rule>
<from>offers.html</from>
<to>offers.jsp</to>
</rule>
I would use OCPsoft PrettyFaces or OCPsoft Rewrite for this:
With PrettyFaces:
create WEB-INF/pretty-config.xml
<url-mapping>
<pattern value="/offers.html" />
<view-id value="/offers.jsp" />
</url-mapping>
With Rewrite:
ConfigurationBuilder.begin()
.addRule(Join.path("/offers.html").to("/offers.jsp"));
I hope this helps.
~Lincoln
Firstly, I'm assuming that when you say "redirect", you really mean "forward". HTTP Redirects would not be appropriate here.
SO given that, here are some things to try:
Can't you just move the JSP files from WebContent into /WEB-INF/jsp/? You wouldn't have to change the ViewResolver definition, then.
You could try to have the controllers return a view name of something like ../../another.jsp, and hope that the servlet container resolves to /WEB-INF/jsp/../../another.jsp to /another.jsp.
The ViewResolver is only consulted if the controllers return the name of a view. Your controllers don't have to return the name of a view, they can return a View object directly, in this case a JstlView. This can point to whichever JSP you like. You can some controllers returning view names, and some returning View objects.
Remove the prefix property from your view resolver. This means you'd also have to change every existing controller, to prefix every view name they return with /WEB-INF/jsp/. Then you could refer to the JSPs under WebContent by name.

How to obtain a current user locale from Spring without passing it as a parameter to functions?

I am using Spring 3.1 and want to find the locale active for the current user is there a way to grab the locale directly without being forced to pass it from the controller to the service layer ... etc.
does spring store the locale in a thread local storage where it can be grabbed by calling some static method?
I was also looking for how to access the locale without passing the Locale around, but I'm still pretty new to Spring and found most solutions to be confusing. It turns out, though, that Spring MVC does store the locale in thread local storage. It can be accessed by:
Locale locale = LocaleContextHolder.getLocale();
The last approach [...] is based on a thread local in order to provide the current locale in any entity of your architecture. [...] You must be aware that the content of the LocaleContextHolder corresponds by default to the locale specified within the Web request.
From: Configuring locale switching with Spring MVC 3. (That post also offers alternative configurations/methods for getting the locale, which might be useful for anyone looking to do this).
You can also view the LocaleContextHolder docs from Spring here.
It depends on where you have configured to store the locale, in session or in cookie?
In my application I have configured to store the user locale in its session with below mentioned configuration.
<mvc:interceptors>
<ref bean="localeChangeInterceptor"/>
</mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/i18n/labels</value>
<value>/WEB-INF/i18n/messages</value>
<value>/WEB-INF/i18n/include</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
If you have done somthing like this then you can easily retrieve the locale parameter from the session.
Hope this helps you.
Cheers.
We had the same need, so came up with putting Locale into ThreadLocal context. We already had an object (some user information) stored in ThreadLocal context, so just appended it (looks like a hack, but the quickest solution we found).

how Spring MVC find its handler mapping

in Spring MVC we can configure handler mapping as bean.but how spring examine what is the handler mapping we mentioned in xml?
simpliy
<bean id="simplehandler" class="" />
do we need to specify "simplehandler" bean id to somewhere for spring to identify bean handler?
First thing that must be clear is that: Spring has several handler mappings.
And the "DefaulAnnotationHandlerMapping" is activated by default (See DispatcherServlet.properties in the Spring distribution or just google for it. All default handlers are listed there). Spring will choose "DefaulAnnotationHandlerMapping" by default.
If you want Spring to use another handler mapping strategy, you have to tell him explicitly
e.g.:
<bean class="org.blablabla......ControllerClassNameHandlerMapping" />
Note that this cancels the use of the default handler mapping strategy
You can also tell Spring to use several handler mapping strategy and prioritized them by using the order property in the mappers declaration
something like
<bean class="org.blabla....DefaulAnnotationHandlerMapping" >
<property name="order" value="0"/>
</bean>
<bean class="org.blablabla......ControllerClassNameHandlerMapping">
<property name="order" value="1"/>
</bean>
Hope this helps. And sorry if the syntax of my bean declaration is not 100% correct. I had to write quickly ;-)

How to mix different types of views in spring configuration?

greetings all
i am using jsp as a view technology in my web app
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
and i want to use velocity too as a view technology in sending emails
and i want to configure this in the xml file, but i don't know how ?
any ideas how to do this ?
If you want to use Velocity to construct emails, then this is not a "view", as far as Spring MVC is concerned. Views and ViewResolvers are used to render output to the browser.
Spring MVC does provide support for using Velocity as a view layer, but this isn't relevant to what you're trying to do.
However, Spring also provides some support classes to make the clunky Velocity API a bit less awkward to use (see javadocs). These have no relation to the Spring MVC view layer, though. Just use them directly from your code, building the emails and sending them.

Spring MVC "redirect:" prefix always redirects to http -- how do I make it stay on https?

I solved this myself, but I spent so long discovering such a simple solution, I figured it deserved to be documented here.
I have a typical Spring 3 MVC setup with an InternalResourceViewResolver:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
I have a pretty simple handler method in my controller, but I've simplified it even more for this example:
#RequestMapping("/groups")
public String selectGroup() {
return "redirect:/";
}
The problem is, if I browse to https://my.domain.com/groups, I end up at http://my.domain.com/ after the redirect. (In actuality my load-balancer redirects all http requests to https, but this just causes multiple browser alerts of the type "You are leaving/entering a secure connection" for folks who have such alerts turned on.)
So the question is: how does one get spring to redirect to https when that's what the original request used?
The short answer is, set the InternalResourceViewResolver's redirectHttp10Compatible property to false:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
<property name="redirectHttp10Compatible" value="false" />
</bean>
You could do this on a per-request basis instead, by having your handler method return View instead of String, and creating the RedirectView yourself, and calling setHttp10Compatible(false).
(It turns out the culprit is HttpServletResponse.sendRedirect, which the RedirectView uses for HTTP 1.0 compatible redirects, but not otherwise. I guess this means it's dependent on your servlet container's implementation (?); I observed the problem in both Tomcat and Jetty.)
Spring Boot provides this nice configuration based solution to this if you're running behind a proxy server, simply add these two properties to your application.properties file:
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
This works for me deploying the otherwise unchanged spring-boot-sample-web-ui to Elastic Beanstalk behind an https load balancer. Without these properties the redirect on line 68 of the MessageController defaults to http and hangs.
Hope this helps.
What worked for me is adding this to application.properties server.tomcat.use-relative-redirects=true
So when you have:
public function redirect() {
return "redirect:/"
}
Without the server.tomcat.use-relative-redirects it will add a Location header like: http://my-host.com/.
With the server.tomcat.use-relative-redirects it will look like: /.
So it will be relative to the current page from browser perspective.
Are you sure?
Looking at the code it seems there is no difference. Both variants use the encoded url, see the sendRedirect method in RedirectView:
String encodedURL = isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl);
if (http10Compatible) {
// Other if/else stuff depending on status code
// Send status code 302 by default.
response.sendRedirect(encodedURL);
}
else {
HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
response.setStatus(statusCode.value());
response.setHeader("Location", encodedURL);
}
I had the same problem, but it was triggered by setting up tomcat behind a loadbalancer. The loadbalancer does the SSL handshake and forwards to tomcat a plain http connection.
Solution would be to send a special Http Header in your Loadbalancer, so tomcat can "trust" this connection. Using a servlet filter should set response.isSecure flag. Then overwrite RedirectView to see if response.isSecure and handle it the right way.
I kept this solution short because i am not sure if it machtes the question.
Since Spring Boot 2.1 you have to add the following configuration to your application.properties:
server.use-forward-headers=true
or application.yml:
server:
use-forward-headers: true
if you use springmvc ,you can try the following:
modelAndView.setView(new RedirectView("redirect url path", true, false));
I add scheme="https" in file server.xml for connector with port="80":
<Connector port="80" protocol="HTTP/1.1" URIEncoding="UTF-8"
connectionTimeout="20000" redirectPort="443" scheme="https" />
This started happening for us on Chrome 87 (https://blog.chromium.org/2020/08/protecting-google-chrome-users-from.html), for a quickfix to avoid the warning page in our springboot app we solve it by adding use-relative-redirects: true in the application.yml.
I was also facing same issue...When redirecting it goes to http instead of HTTPS , below changes done :
RedirectView redirect = new RedirectView("/xyz",true);
redirect.setExposeModelAttributes(false);
redirect.setHttp10Compatible(false);
mav = new ModelAndView(redirect);

Resources