好的,我對這個主題有一個賞金,只有部分答案,所以我打開這個主題並簡化主題,因爲我猜原來的主題太臃腫了。服務工廠實例化bean如何訪問httpServletRequest對象?
我面臨的情況是,我基本上有一個過濾器,它從servlet上下文獲取Spring服務工廠對象,當過濾器調用它的getService方法時,該工廠分配一個bean的實例,但我需要訪問會話或請求的實際httpServletRequest對象,因爲我需要來自請求的用戶ID。我認爲,從我讀過的內容來看,我不應該將它傳遞給bean,這不僅因爲它不是線程安全的,而且還因爲它會打破擁有過濾器的遠程服務橋(CP2JavaWS)的抽象。
我怎樣才能讓這個bean訪問會話或httpServletRequest?
我嘗試使用FacesContext,但它沒有奏效,因爲我認爲這個bean沒有被一個jsp調用實例化,而是來自一個過濾器。
現在有些代碼。
這是我的web.xml
<display-name>CP2JavaWSTest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/err.jsp</location>
</error-page>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.cp2javaws.listeners.SpringContextWrapperListener</listener-class>
</listener>
<listener>
<listener-class>com.bucle.listeners.BCLUserDatabaseContextListener</listener-class>
</listener>
<filter>
<filter-name>BCLAuthenticationFilter</filter-name>
<filter-class>com.bucle.filters.BCLAuthenticationFilter</filter-class>
</filter>
<filter>
<filter-name>BCLAuthorizationFilter</filter-name>
<filter-class>com.bucle.filters.BCLAuthorizationFilter</filter-class>
</filter>
<filter>
<filter-name>CPJSonFilter</filter-name>
<filter-class>com.cp2javaws.filters.CPJSonFilter</filter-class>
</filter>
應用程序上下文:
<bean id="service1" class="com.bucle.database.BCLDb4oManager" scope="request"/>
<bean id="service2" class="com.bucle.services.appe.BCLUserCFVC"/>
<bean id="service3" class="com.bucle.services.appe.BCLUserCustomizedFutureValueCalculator"/>
的CPWJavaWS過濾
public class CPJSonFilter implements Filter {
//.. properties
public void init(FilterConfig filterConfig)
throws ServletException {
//.. init code
}
public void destroy() {
//..
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpSession session = ((HttpServletRequest)request).getSession(true);
//..Class and method decoding and mapping from JSON
Class type = null;
String value = request.getParameter(CP2JavaWSRequestParameterType+paramOrderString);
if(paramName.indexOf(CP2JavaWSRequestGenericParamSuffix)>0 || request.getParameter(CP2JavaWSRequestParameterType+paramOrderString).equals("id")) {//SAMIR
type = Object.class;
} else {
if(paramName.indexOf(CP2JavaWSRequestNullParamSuffix)>0) {
String CPClassName = paramName.substring(paramName.indexOf(CP2JavaWSRequestNullParamSuffix)+CP2JavaWSRequestNullParamSuffix.length());
try {
type = getJavaClassForCPClass(CPClassName);
} catch (CP2JavaWSException e) {
throw new ServletException("Cannot find corresponding Java class for null argument at index "+paramOrderString+" (passed CP class name is"+CPClassName+")");
}
} else if(List.class.isAssignableFrom(convertedObject.getClass())) {
type = List.class;
} else if(Map.class.isAssignableFrom(convertedObject.getClass())) {
type = Map.class;
} else {
type = convertedObject.getClass();
}
}
typesOrderedMap.put(new Integer(paramOrderString), type);
}
}
// invoke the service method using the provided service factory class
Object result = null;
try {
Class serviceInterfaceClass = Class.forName(serviceInterfaceName);
ServiceFactory serviceFactory = (ServiceFactory) filterConfig.getServletContext().getAttribute(ServiceFactory.CP2JAVAWS_SERVICES_FACTORY);
Object service = serviceFactory.getService(serviceInterfaceClass);
Method method = service.getClass().getDeclaredMethod(serviceMethodName, (Class[]) typesOrderedMap.values().toArray(new Class[typesOrderedMap.size()]));
result = method.invoke(service, argumentsOrderedMap.values().toArray());
} catch(Exception e) {
throw new ServletException("Error invoking the service method :"+serviceMethodName+" on service "+serviceInterfaceName,e);
}
//...Convert result to JSON
response.setContentType("application/json");
PrintWriter writer = response.getWriter();
StringBuffer stb = new StringBuffer();
//... append result and some other stuff to the string buffer stb
response.setContentLength(stb.length());
((HttpServletResponse)response).setStatus(HttpServletResponse.SC_OK);
writer.write(stb.toString());
writer.flush();
}
public static Class getJavaClassForCPClass(String CPClassName) throws CP2JavaWSException {
//... returns the matching Class.class according to a default map like: CPArray -> List.class
}
}
這是Spring上下文監聽器:
public class SpringContextWrapperListener implements ServletContextListener {
private ServletContext context = null;
public void contextDestroyed(ServletContextEvent event) {
this.context = null;
//log.info("Spring Context Destruido");
}
public void contextInitialized(ServletContextEvent event) {
this.context = event.getServletContext();
ApplicationContext springContext = (ApplicationContext) WebApplicationContextUtils.getRequiredWebApplicationContext(this.context);
SpringContextWrapper aSpringContextWrapper = new SpringContextWrapper(springContext);
this.context.setAttribute(ServiceFactory.CP2JAVAWS_SERVICES_FACTORY, aSpringContextWrapper);
}
}
和工廠:
public class SpringContextWrapper implements ServiceFactory {
private ApplicationContext springContext;
public SpringContextWrapper(ApplicationContext springContext) {
this.springContext = springContext;
}
public Object getService(Class serviceInterfaceClass) throws CP2JavaWSException {
Map services = this.springContext.getBeansOfType(serviceInterfaceClass);
Iterator it = services.values().iterator();
if(it.hasNext()) {
return it.next();
}
throw new CP2JavaWSException("can't find service for interface "+serviceInterfaceClass.getName());
}
public Object getService(String serviceName) throws CP2JavaWSException {
Object service = this.springContext.getBean(serviceName);
if(service==null) {
throw new CP2JavaWSException("can't find service for name "+serviceName);
}
return service;
}}
我張貼此作爲一個評論,因爲我還沒有使用它factorymethods但僅限於控制器尚未:使用Spring,你可以使用參數解析器注入需要的對象成你的方法。有一個localeargumentresolver以及您可以在您的請求映射方法中使用的requestargumentresolver。基本上這些是關於如何處理框架調用的方法的參數的合約。也許這只是工廠方法? – 2013-04-30 05:03:54
謝謝你回答馬丁,NilsH的答案很容易測試,它確實有用,但我會更深入地研究你對解決問題的解決方案的回答,因爲我的春天的知識是基本的。它也可能工作。不要擔心,我不會投下它。 – Jigzat 2013-05-01 21:05:31