简体   繁体   中英

Can we use @autowired in jsp. If yes then how.?

I am building a web application using spring and hibernate. I wanted to build the server side table for that I need a method that is written in Service class. But to execute it successfully I need to autowire it to the repected class as for now it is giving a Null Pointer Exception accessing the table.

No you can't use @autowired in JSP. If you need a bean in JSP, you can use the following :

ApplicationContext ac = RequestContextUtils.getWebApplicationContext(request);
ac.getBean("yourBeanName");

Edited to :-

Example Bean :

@Component("abcBean")
public Abc{

    public void sysout(){
        System.out.printn("Hello world");
    }

}

In JSP:

You can use this spring managed singleton bean as:

ApplicationContext ac = RequestContextUtils.getWebApplicationContext(request);
Abc abc = (Abc) ac.getBean("abcBean");
abc.sysout();

Please post if anything else is required.

If you are using Spring MVC you can pass your service to the JSP thanks to a ModelAndView.

Suppose you have : Controller

@Controller
public void MyController {

    @Autowired
    private MyServiceInterface myService;

    @RequestMapping(value="myUrl")
    public ModelAndView displayPage() {
       //do some stuff
        return new ModelAndView("myView").addObject("myService", myService);
    }
}

JSP :

<html>
.
${myService.myMethodIWantToUse}
.
</html>

But like Slava Semushin said, it's a bad practice. If you are excepting results from your method and print them in your JSP, put them in your model (ModelAndView)

NO. You can not autowire beans in JSP. Beans are autowired in classes which are annotated themselves. Any class which is annotated with @Component or child of @Component can annotate other beans.

This is not the ideal way to do in an MVC application, You should make an HTTP call to the controller if you need to fetch something from the service.

Beans cannot be autowired in the the JSP. You will have to use the RequestContextUtils class to fetch beans defined in the spring container .

If you're using Tomcat, yes, but it takes some work.

The solution is to wrap the normal tomcat instance manager (what it uses to instantiate JSP instances) and then to inject the wrapped version through a listener.

First, the wrapping manager class. It's pretty simple and just injects beans in newly created objects before returning them.

public class SpringInstanceManager implements InstanceManager {

    ServletContext ctx;
    InstanceManager manager;

    public SpringInstanceManager(ServletContext ctx, InstanceManager manager){
        this.ctx = ctx;
        this.manager = manager;           
    }

    public Object processAnnotations(Object o) throws IllegalAccessException, InvocationTargetException, NamingException {
        if (o != null && o.getClass().getName().endsWith("_jsp")){             
            SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(o, ctx);
        }
        return o;
    }

    @Override
    public Object newInstance(Class<?> clazz) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException {
        return processAnnotations(manager.newInstance(clazz));
    }

    @Override
    public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
        return processAnnotations(manager.newInstance(className));
    }

    @Override
    public Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
        return processAnnotations(manager.newInstance(fqcn, classLoader));
    }

    @Override
    public void newInstance(Object o) throws IllegalAccessException, InvocationTargetException, NamingException {
        manager.newInstance(o);
    }

    @Override
    public void destroyInstance(Object o) throws IllegalAccessException, InvocationTargetException {
        manager.destroyInstance(o);
    }
}

And then we add a listener to inject it on context startup:

public class SpringJSPEnablerListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        InstanceManager oldManager =  ((InstanceManager) (context.getAttribute(InstanceManager.class.getName())));
        if (!(oldManager instanceof SpringInstanceManager)) {
            InstanceManager springInjectingInstanceManager = new SpringInstanceManager(context,oldManager);
            context.setAttribute(InstanceManager.class.getName(), springInjectingInstanceManager);
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {}
}

Then in the JSP pages you can use something like this

<%! @Autowired MyClass myClassInstance %>

and it should work correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM