public class ProductsResource01 {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private ProductsService productsService;
public void getProductsList(){
List<Products> list = productsService.getAll();
for(Products a : list){
System.out.println(a);
}
}
public static void main(String[] args) {
ProductsResource01 p01 = new ProductsResource01();
p01.getProductsList();
}
Bug信息:
Exception in thread "main" java.lang.NullPointerException
at cn.syy.otherUtils.ProductsResource01.getProductsList(ProductsResource01.java:18)
at cn.syy.otherUtils.ProductsResource01.main(ProductsResource01.java:26)
18行 productsService 这个对象是空的,没有注入进来。productsService 注解是@AutoWired 是有容器管理其生命周期的,如你直接用main来new ProductsResource01对象, productsService没有注进来,所以报空指针,这种做单元测试可以用Junit
将上面的方法设为静态的static修饰下。main函数是静态的 所以只可以 掉用静态的。
productsService为空,注入没生效,检查一下Spring配置吧
@autowired 注入实现,需要加载配置spring配置文件,这个你应该知道了 。
但是main()方法去执行的时候,只会加载本类和main方法中用来的类文件,而不会读取==加载spring配置文件,
自然你的service参数是注入不进来,是空指针的。
如果你用tomcat、junit等启动项目的方式,会加载spring配置文件,自然就注入进来了 。
当然,如果你用spring的 new XmlClassPathApplication("spring配置文件位置"),显示直接加载文件,那么一样可以注入 。
@Autowired
private ProductsService productsService;
断点 List list = productsService.getAll();这个productsService为null,没有注入。
没有注入进去,检查spring配置文件
大家回答的根本原因都差不多相同,我在单元测试确实service层注入了进来,junit测试确实return得到了数据;
然后Tomcat部署运行control层,却是空指针异常:
控制层代码如下:
@Controller("ViewProductsJSP")
@Path("/view")
public class ViewProductsJSP {
static Log log = LogFactory.getLog("控制类ViewProductsJSP运行信息:"+ViewProductsJSP.class);
@Autowired
private ProductsService productsService;
//通过request请求转发方式从rest风格的请求跳转到jsp页面-传递request域参数
@GET
@Path("products")
@Produces(MediaType.TEXT_PLAIN_VALUE)
public List<Products> getProductsList(@Context HttpServletRequest request,@Context HttpServletResponse response) throws ServletException, IOException{
log.info("request dispatcher...to jsp");
//获得products数据并传入数据
List<Products> list = productsService.getAll();
log.info("产品信息"+list);
request.setAttribute("products", list);
//请求转发
request.getRequestDispatcher("products.jsp").forward(request, response);
return list;
}
运行结果:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: java.lang.NullPointerException
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)
root cause
java.lang.NullPointerException
cn.syy.web.ViewProductsJSP.getProductsList(ViewProductsJSP.java:45)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
然后考虑到service层注入未成功,又写了个类工具,代码如下:
package cn.syy.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringUtil implements ApplicationContextAware {
//当前IOC
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
applicationContext = arg0;
}
//从当前IOC获取bean
public static Object getObject(String id) {
Object object = null;
object = applicationContext.getBean(id);
return object;
}
}
修改control类,代码如下:
@Controller("ViewProductsJSP")
@Path("/view")
public class ViewProductsJSP {
static Log log = LogFactory.getLog("控制类ViewProductsJSP运行信息:"+ViewProductsJSP.class);
//前提:Spring自动装配
@Autowired
private static ProductsService productsService = (ProductsService)SpringUtil.getObject("productsService");
// private ProductsService productsService;
//通过request请求转发方式从rest风格的请求跳转到jsp页面-传递request域参数
@GET
@Path("products")
@Produces(MediaType.TEXT_PLAIN_VALUE)
public List<Products> getProductsList(@Context HttpServletRequest request,@Context HttpServletResponse response) throws ServletException, IOException{
log.info("request dispatcher...to jsp");
//获得products数据并传入数据
List<Products> list = productsService.getAll();
log.info("产品信息"+list);
request.setAttribute("products", list);
//请求转发
request.getRequestDispatcher("products.jsp").forward(request, response);
return list;
}
然后运行结果报错500异常:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: A MultiException has 2 exceptions. They are:
1. java.lang.ExceptionInInitializerError
2. java.lang.IllegalStateException: Unable to perform operation: create on cn.syy.web.ViewProductsJSP
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:421)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:222)
root cause
A MultiException has 2 exceptions. They are:
1. java.lang.ExceptionInInitializerError
2. java.lang.IllegalStateException: Unable to perform operation: create on cn.syy.web.ViewProductsJSP
org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:394)
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
root cause
java.lang.ExceptionInInitializerError
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129)
org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)
org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:169)
---------------------------
spring-serviece层的配置:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 扫描service包下所有使用注解的类型 -->
<context:component-scan base-package="cn.syy.service" />
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置基于注解的声明事务,默认使用注解来管理事务行为 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 4-20 start-->
<bean id="springUtil" class="cn.syy.utils.SpringUtil" />
Web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<!-- 修改servlet版本为3.0 -->
<!-- 修改web.xml,配置jerseyServlet -->
ProductsRecordSys
springConfig
classpath:spring/spring-*.xml
jerseyServlet
org.glassfish.jersey.servlet.ServletContainer
<!-- com.sun.jersey.spi.spring.container.servlet.SpringServlet -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>cn.syy.web.RestApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.Redirect</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>jersey.config.servlet.filter.forwardOn404</param-name>
<param-value>true</param-value>
</init-param>
jerseyServlet
/jsp/*