Spring service NullPointerException jakarta webservice


@Path("/abc")
@Produces(MediaType.APPLICATION_JSON)
public class ABCController
{
@Autowired
private MyService myService;
@GET
public Response getSome(@QueryParam("identification") List<String> ids)
{
GenericEntity<List<Label>> entity = new GenericEntity<>(myService.findSomething(ids))
{
};
return Response.ok(entity).build();
}

我的服务:

@RequiredArgsConstructor
@Service
public class MyService
{
private final MyMapper myMapper;
private final JpaRepository myRepository;
public List<String> findSomething(ids){
myRepository.findXYZ(ids);
}

我的主课:

@SpringBootApplication
public class MainClass
{
public static void main(String[] args)
{
SpringApplication.run(MainClass.class, args);
}
@Bean
public MyMapper myMapper()
{
return new MyMapperImpl();
}
}

build.gradle:

buildscript {
ext {
LOMBOK_VERSION = "1.18.22"
SPRING_BOOT_VERSION = "2.6.6"
JERSEY_VERSION = "3.0.8"
JACKSON_VERSION = "2.13.1"
MSSQL_JDBC_VERSION = "9.4.1.jre11"
MAPSTRUCT = "1.5.1.Final"
}
}
plugins {
id "org.gretty" version "4.0.3"
}
apply plugin: 'java-library'
apply plugin: 'java'
apply plugin: 'war'
repositories {
mavenLocal()
maven {
url = '...'
}
}

dependencies {
compileOnly "org.projectlombok:lombok:${LOMBOK_VERSION}"
testImplementation "org.projectlombok:lombok:${LOMBOK_VERSION}"
annotationProcessor "org.projectlombok:lombok:${LOMBOK_VERSION}"
implementation "org.mapstruct:mapstruct:${MAPSTRUCT}"
annotationProcessor "org.mapstruct:mapstruct-processor:${MAPSTRUCT}"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${SPRING_BOOT_VERSION}"
implementation "com.microsoft.sqlserver:mssql-jdbc:${MSSQL_JDBC_VERSION}"
implementation "org.glassfish.jersey.containers:jersey-container-servlet-core:${JERSEY_VERSION}"
implementation "org.glassfish.jersey.inject:jersey-hk2:${JERSEY_VERSION}"
implementation "org.glassfish.jersey.media:jersey-media-json-jackson:${JERSEY_VERSION}"
}

当我打电话给http://localhost:8080/myservice/abc?identification=61234561234569,71234561234568,71234561234569

我得到了myService.findSomething(ids)NullPointerException

我使用 gradle 命令启动应用程序appRun

尽管 spring带来了自己的"REST-Service 开发框架"(spring-web),但 JAX-RS 没有理由不能使用 spring-core 甚至 spring-boot。


问题(对于该特定 NPE)是:

对于自动布线:两个(有线和布线)对象都需要"弹簧管理(豆)"!;)在MyService中,这是通过@Service注释实现的。

为了解决这个问题,我们也需要在春季环境中参与ABCController!


"侵入性最小"/最简单的方法 - 用@Component注释ABCController

...
import org.springframework.stereotype.Component;
@Component // !
@Path("/abc")
@Produces(MediaType.APPLICATION_JSON)
public class ABCController ...

这(+正确的"组件扫描")将"提升"ABCController到弹簧上下文中,并启用自动连接(从/到)该对象。


另一种方法,将"实现"与 spring 分离:

为此,我们需要从"弹簧独立"类中删除所有(可能的)org.springframework.*导入。(当然,在非常 Spring 特定的类(spring-web(Rest)Controllers、Spring-data-repos, ...)中这是不可能的。

  • 为了替换@Component/Service/Repository注释,我们将实例化移动到@Bean注释方法到我们的 spring 配置(类)(..见我的映射豆!
  • 要替换@Autowired我们必须"手动连接"它们或使用"隐式构造函数自动连接"(在上述@Bean方法中)

所以你的 Config(/SpringBootApp) 可能看起来像:

@SpringBootApplication
public class MainClass
{
public static void main(String[] args)
{
SpringApplication.run(MainClass.class, args);
}
@Bean
public MyMapper myMapper()
{
return new MyMapperImpl();
}

@Bean // singleton is default "scope"!!...
public MyService myService(/*implicitly @Autowired :*/ JPARepository repo, MyMapper mapper /* ..and taken care (hopefully;) by spring*/) {
return new MyService(mapper, repo);
}
// and:
@Bean 
public ABCController abcController(/*implicitly @Autowired :*/ MyService service /* ..and taken care (hopefully;) by spring*/) {
ABCController bean = new ABCController();
bean.setMyService(service);
return bean; 
}
}

通过对ABCController的相应调整:


@Path("/abc")
@Produces(MediaType.APPLICATION_JSON)
public class ABCController
{
// NOT @Autowired
private MyService myService;
...
// Setter(/getter) for myService !

是春季靴中球衣的依赖关系:spring-boot-starter-jersey

build.gradle 看起来像这样:

buildscript {
ext {
LOMBOK_VERSION = "1.18.22"
SPRING_BOOT_VERSION = "2.6.6"
JERSEY_VERSION = "3.0.8"
JACKSON_VERSION = "2.13.1"
MSSQL_JDBC_VERSION = "9.4.1.jre11"
MAPSTRUCT = "1.5.1.Final"
}
}
apply plugin: 'java-library'
apply plugin: 'java'
apply plugin: 'war'
repositories {
mavenLocal()
maven {
...
}
}

dependencies {
compileOnly "org.projectlombok:lombok:${LOMBOK_VERSION}"
testImplementation "org.projectlombok:lombok:${LOMBOK_VERSION}"
annotationProcessor "org.projectlombok:lombok:${LOMBOK_VERSION}"
implementation "org.mapstruct:mapstruct:${MAPSTRUCT}"
annotationProcessor "org.mapstruct:mapstruct-processor:${MAPSTRUCT}"
implementation "org.springframework.boot:spring-boot-starter-jersey:${SPRING_BOOT_VERSION}"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${SPRING_BOOT_VERSION}"
implementation "com.microsoft.sqlserver:mssql-jdbc:${MSSQL_JDBC_VERSION}"
}

控制器成为@Component

@Path("/abc")
@Produces(MediaType.APPLICATION_JSON)
@Component
public class ABCController
{
@Autowired
private MyService myService;
@GET
public Response getSome(@QueryParam("identification") List<String> ids)
{
GenericEntity<List<Label>> entity = new GenericEntity<>(myService.findSomething(ids))
{
};
return Response.ok(entity).build();
}

MainClass 是 servlet:

@SpringBootApplication
public class MainClass extends SpringBootServletInitializer
{
public static void main(String[] args)
{
new MainClass().configure(new SpringApplicationBuilder(MainClass.class)).run(args);
}
@Bean
public MyMapper myMapper()
{
return new MyMapperImpl();
}
}

我的服务是一个@Service

@RequiredArgsConstructor
@Service
public class MyService
{

我添加了一个泽西配置:

@Component
public class JerseyConfig extends ResourceConfig
{
public JerseyConfig()
{
register(ABCController.class);
}
}

相关内容

  • 没有找到相关文章