kurochenko
kurochenko

Reputation: 1254

Spring 3 how to handle multilanguage URL with same content

I want to fully internationalize my web page and have URLs translated to different languages. For example

all aforementioned pages should be handled by same controller and show same content (translated to desired language of course, this i know how to do - using message properties).

So my questions are:

  1. How to achieve this functionality using @RequestMapping annotation?
  2. Can I configure such aliases in properties or XML file and then "inject" them into controller? i.e.:

properties file:

alias.page=page:pagina

Controller

@RequestMapping("${alias.page}")
...

Or something like this.

Thanks for answers.

Upvotes: 9

Views: 3111

Answers (2)

kurochenko
kurochenko

Reputation: 1254

I've solved this issue by creating own implementation of servlet Filter

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class ExampleFilter implements Filter {

    @Override
    public void init(FilterConfig fc) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain fc) throws IOException, ServletException {

        // Needed for getting URL from request
        final HttpServletRequest hsRequest = (HttpServletRequest) request;
        String url = hsRequest.getRequestURI().substring(
                        hsRequest.getContextPath().length()
                     );

        /* This is just simple example. Here you can connect to database
           or read properties or XML file with your configuration */
        if ("/de/pagina".equals(url) || "/en/page".equals(url)) {
            // change url and forward 
            RequestDispatcher dispatcher = request.getRequestDispatcher("/page");
            dispatcher.forward(request, response);
        } else {
            // Do nothing, just send request and response to other filters
            fc.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {}
}

The controller method to handle request will then look like

@Controller
public class MultiLangController {

    @RequestMapping(value="/page", method = RequestMethod.GET)
    public String pageMethod() {        
        return ...;
    }    
}

Finally publish the new filter into web.xml

<filter>
    <filter-name>MyExampleFilter</filter-name>
    <filter-class>
        com.path.to.filter.ExampleFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>MyExampleFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

And that should do the trick. If you don't need such flexibility, maybe UrlRewriteFilter (analogue of .htaccess for Java) will be sufficient.

Upvotes: 5

atrain
atrain

Reputation: 9255

Use a PathVariable in the @RequestMapping, with something before it so Spring can map the request:

@RequestMapping("myPage.do")
public String displayBasePage () {
   return("pageName"); // a hard-coded JSP
}

becomes

@RequestMapping("/someidentifier/{pageName}.do"
public String displayBasePage (
      PathVariable("pageName") String pageName) {
   return(pageName); // the language-specific JSP, or whatever else you want to do
}

Spring will match the /someidentifier/ to this RequestMapping, and you can use whatever value you want for the pageName.

Upvotes: -1

Related Questions