Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • http://example.tld/en/page
  • http://example.tld/de/pagina

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.

like image 709
kurochenko Avatar asked Jul 07 '11 12:07

kurochenko


1 Answers

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.

like image 125
kurochenko Avatar answered Oct 20 '22 09:10

kurochenko