Spring - как получить ServletContext в @Service (+ как получить манифест WebApps)

В веб-приложении @Controllers вы можете autowire ваш контекст сервлета, чтобы вы могли (в моем случае) получить манифест из веб-приложения (см. qaru.site/info/43061/...).

@Autowired
ServletContext servletContext;

Как вы получаете это в сервисе?

Я реализовал этот простой шаблон и думал, что буду делиться.

Ответ 1

Обновление: это плохое решение, так как оно заставляет сервис зависеть от клиента. См. Ниже обновленное решение.

Просто с @PostConstruct, чтобы служба имела ServletContext, установленную до того, как она будет отключена.

@Controller
@RequestMapping("/manifests")
public class ManifestEndpoint {
    @Autowired
    private ManifestService manifestService;

    @Autowired
    ServletContext servletContext;

    @PostConstruct
    public void initService() {
        manifestService.setServletContext(servletContext);
    }

Затем в сервисе обязательно убедитесь, что он используется, поскольку это невозможно.

@Component
public class ManifestService {
    ....
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    private void buildManifestCurrentWebApp() {
        if (servletContext == null) {
            throw new RuntimeException("ServletContext not set");
        }
        # Here how to complete my example on how to get WebApp Manifest
        try {
            URL thisAppsManifestURL = servletContext.getResource("/META-INF/MANIFEST.MF");
            System.out.println("buildManifestCurrentWebApp - url: "+thisAppsManifestURL);
            buildManifest(thisAppsManifestURL);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

Обновленное решение, которое не заставляет сервис зависеть от клиента.

@Controller
@RequestMapping("/manifests")
public class ManifestEndpoint {
    private static final Logger logger = LoggerFactory.logger(ManifestEndpoint.class);
    @Autowired
    private ManifestService manifestService;

    @Autowired
    private ServletContext servletContext;

    @PostConstruct
    public void initService() {
        // We need to use the Manifest from this web app.
        URL thisAppsManifestURL;
        try {
            thisAppsManifestURL = servletContext.getResource("/META-INF/MANIFEST.MF");
        } catch (MalformedURLException e) {
            throw new GeodesyRuntimeException("Error retrieving META-INF/MANIFEST.MF resource from webapp", e);
        }
        manifestService.buildManifest(thisAppsManifestURL);
    }

ManifestService не изменяется (т.е. теперь нет необходимости в buildManifestCurrentWebApp()).