将HTTP请求处理从Spring MVC控制器委托给Jersey 2

我正在尝试将我的一组RESTful终结点(依赖于 Jersey 2 JAX-RS实现)插入运行在顶部的第三方 Spring MVC Web应用程序中的是 Tomcat 9。

不允许我修改web.xml,也不能在容器启动时使用我的插件,因此annotation-based configuration也不可行。这意味着我不能直接部署 Jersey ServletContainer

am 所允许的是插入 Spring MVC ,即

  1. 创建自定义的部分 Spring 应用程序上下文和
  2. 实现自定义Controller,所以我写了这个天真的实现,它实际上接近于标准ServletWrappingController
package com.example

import org.glassfish.jersey.server.ResourceConfig
import org.glassfish.jersey.servlet.ServletContainer
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.AbstractController
import java.io.IOException
import java.util.Collections
import java.util.Enumeration
import javax.servlet.ServletConfig
import javax.servlet.ServletContext
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class JerseyServletInitializer(servletContext: ServletContext,componentClasses: List<Class<*>>,components: List<Any>): AbstractController() {
    private val servletContainer: ServletContainer

    init {
        val resourceConfig = ResourceConfig()
            .apply {
                // Register org.glassfish.jersey.media.multipart.MultiPartFeature
                componentClasses.forEach { clazz ->
                    register(clazz)
                }
                // Register REST endpoints
                components.forEach { component ->
                    register(component)
                }
            }

        // Provide a dummy ServletConfig
        val servletConfig = object : ServletConfig {
            override fun getInitParameter(name: String): String? = null

            override fun getInitParameterNames(): Enumeration<String> = emptyList<String>().let {
                Collections.enumeration(it)
            }

            override fun getServletName(): String = ServletContainer::class.java.name

            override fun getServletContext(): ServletContext = servletContext
        }

        // Create and initialize Jersey's ServletContainer
        servletContainer = ServletContainer(resourceConfig).apply {
            init(servletConfig)
        }

        setSupportedMethods("GET","POST","PUT","OPTIONS")
    }

    @Throws(IOException::class)
    override fun handleRequestInternal(request: HttpServletRequest,response: HttpServletResponse): ModelAndView? {
        // Delegate all HTTP requests to Jersey
        servletContainer.service(request,response)
        return null
    }
}

除了文件上传方案(即HTTP POSTContent-Type: multipart/form-data)之外,上述方法都可以正常工作。

Spring 检测到此类请求并将常规HttpServletRequest转换为MultipartHttpServletRequest,读出并耗尽其输入流(mark() / reset()不支持)。该Web应用程序具有一个自定义MultipartResolver,该自定义不能以任何方式影响

  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

这意味着 Jersey 收到包含空请求正文的多部分HTTP POST,抛出MIMEParsingException并以HTTP 400 Bad Request进行响应。

据我了解,多部分分辨率只能全局禁用,不能在每个控制器的基础上禁用(123)。

问题:

  1. 解决MultipartResolver从而使 Jersey 收到未修改的请求的最佳方法是什么?
  2. 或者,您可以推荐一个API来重新构造请求主体(即与MultipartResolver所做的相反,并将新的HttpServletRequest馈送到 Jersey )吗?当然,这可以手工完成,但是我宁愿依赖现有的库。
iffta 回答:将HTTP请求处理从Spring MVC控制器委托给Jersey 2

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3146015.html

大家都在问