stimpy
stimpy

Reputation: 492

Spring and returning protected resources

I have a pretty standard Spring 3.0.7 web app

The structure is like this

WebContent/
    resources/
      myStaticConent/
    WEB-INF/
       views/
       myProtectedContent/

I am using the <mvc:resources> configuration for the static content and my controllers get views using the InternalViewResolver from WEB-INF/views

Now I have a requirement to return non-JSP content ( JPGs,PNGs,HTML,etc ) from a protected directory in WEB-INF

So a user might enter a URL like http:myWebApp/myProtectedContent and hit my protected content controller.

@Controller
public class HelloWorldController {

@RequestMapping(value="/myProtectedContent")
public String index() {
  return "myjpg.jpg";
 }
}

Essentially I want to conditionally serve a file just like I would a view. Anyone know how this can be done ?

I looked at some of the other methods here, Streaming using Inputstream seems overkill for files that are essentially static. Can I register another "view" type ? I need this to appear l( from the web browser side ) like a standard http request response ( like the current view implementation).

I would really like to avoid inventing my own file handling methods unless there is some reason why using the file access methods are better then Springs "other" view resolvers like ResourceBundleResolver

So the requirement is Conditionally respond to a http request with variable file type (jpg,png,html) from inside WEB-INF without wrapping in a jsp or having the file interpreted by the JSTL view. The names of the files are known and static. The controller will determine the file name based on its own business logic.

Upvotes: 0

Views: 789

Answers (2)

Biju Kunjummen
Biju Kunjummen

Reputation: 49935

You can reproduce the behavior of the underlying implementation of <mvc:resources/> which is org.springframework.web.servlet.resource.ResourceHttpRequestHandler, which essentially streams out the content of the static files - You can like ResourceHttpRequestHandler, extend from org.springframework.web.servlet.support.WebContentGenerator which has extensive support for sending last-modified and caching related headers, and finally to stream the content also there is a utility that Spring provides:

org.springframework.util.FileCopyUtils.copy(resource.getInputStream(), response.getOutputStream());

Updated:

@Controller
public class HelloWorldController implements ApplicationContextAware  {
    ApplicatonContext ctx = ...;

    @RequestMapping(value="/myProtectedContent")
    public void index(HttpServletRequest req, HttpServletResponse res) {
        Resource resource = ctx.getResource("classpath:staticpath/myjpg.jpg");
        FileCopyUtils.copy(resource.getInputStream(), response.getOutputStream());
    }
}

Upvotes: 1

Vitor Braga
Vitor Braga

Reputation: 2212

Something you can do is to map a new servlet to the path you want to be protected and handle the request the way you want.

For example, in web.xml:

<servlet>
    <servlet-name>protServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/protServlet-context.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>protServlet</servlet-name>
    <url-pattern>/myProtectedContent</url-pattern>
</servlet-mapping>

This way, you map a new servlet (DispatcherServlet) for URLs that are protected content. The load-on-startup value equals 2 is due if you already have a DispatcherServlet with this field value equals 1.

Upvotes: 0

Related Questions