Announcement Announcement Module
Collapse
No announcement yet.
How to inject request scoped web service port? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to inject request scoped web service port?

    I have Spring MVC based web application that calls web service. Web service requires http based authentication for every call.I hold web Service Proxy configuration in applicationContext.xml:
    Code:
    <beans...
    
    <bean id="paymentWebService"
          class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
        <property name="customProperties">
            <ref local="jaxwsCustomProperties"/>
        </property>
        <property name="serviceInterface" value="com.azercell.paymentgateway.client.PaymentGatewayWebService"/>
        <property name="wsdlDocumentUrl"
                  value="#{config.wsdlDocumentUrl}"/>
        <property name="namespaceUri" value="http://webservice.paymentgateway.azercell.com/"/>
        <property name="serviceName" value="PaymentGatewayWebServiceImplService"/>
        <property name="portName" value="PaymentGatewayWebServiceImplPort"/>
    </bean>
    I have instance field for web service port in my controller:

    Code:
    @Controller
    public class PaymentController {
    
    @Resource(name = "paymentWebService")
    private PaymentGatewayWebService paymentPort;
    
    @ModelAttribute
    public void ajaxAttribute(WebRequest request, Model model) {
        UtilMethods.authenticationWebServicePort(paymentPort);
        ...
    }
    ...
    
    @RequestMapping(value = "/massPayment", method = RequestMethod.POST)
    public String massPayment(@RequestParam String amount, @RequestParam MultipartFile file, Model model, Locale locale) {
        ...
    
        WebServiceResponse response = paymentPort.massPayment(UtilMethods.getNewRequestId()
                 , fileUploader, UtilMethods.getAmountInCoins(amountBigDecimal), null);
    
        ...      
    
        return SpringView.MASS_PAYMENT.toString(ajaxRequest);
       }
    }
    Code of UtilMethods.authenticationWebServicePort:

    Code:
    public static void authenticationWebServicePort(PaymentGatewayWebService paymentPort) {
        String username = (String) RequestContextHolder.currentRequestAttributes().getAttribute(USERNAME_SESSION_VARIABLE_NAME, RequestAttributes.SCOPE_SESSION);
        String password = (String) RequestContextHolder.currentRequestAttributes().getAttribute(PASSWORD_SESSION_VARIABLE_NAME, RequestAttributes.SCOPE_SESSION);
        BindingProvider prov = (BindingProvider) paymentPort;
        prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
        prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
    }
    As controllers are singleton objects there occurring problems every time when requests overlap, if to be precisely one user by mistake can use web methods with username and password that belong to another user.

    To prevent this I tried to make web service port request scoped in configuration as below:

    Code:
    <bean id="paymentWebService"
      class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean" scope="request">
    in this case I got error:

    Code:
        SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0' while setting constructor argument with key [2]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' while setting bean property 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authentication.ProviderManager#0': Cannot resolve reference to bean 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.authenticationManager': Cannot resolve reference to bean 'myAuthenticationProvider' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myAuthenticationProvider': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'paymentWebService': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    How to create request scoped web service port?
Working...
X