最近一项目,遇到一个变态客户,要用WebService作验证,来进行单点登陆,本来单点登陆也没有这么搞的,没办法,客户是蛮不讲理的那种,下面我们来小试牛刀一下。
一、创建WebService服务端的代码我就不说了,网上有不少用AXIS编写的代码,不过抄袭者众多,而且很多代码是很难与实际项目整合的,实际布署起来更是不可行,比如布署到IBM AIX系统上。
二、创建好服务端后,我们需要对Struts2的过滤器进行简单的改写,以便让客户端程序能正常访问WebService服务端。
三、在你的项目中创建一个包:org.apache.struts2.dispatcher,注意,这个包必须和Struts2中的过滤器包一样,并创建一个类,FilterDispatcher,接下来我们在doFilter中加入如下代码:
if("/WebServiceTest2/services/HelloWordWeb".endsWith(request.getRequestURI())||"/servlet/".endsWith(request.getRequestURI()))
{
chain.doFilter(req,res);
}
这段代码是把webService中的服务器地址和AXIS中配置的servlet让过滤器放行。这样,我们的服务端就不会被拦截了。
四、整段代码如下:
/*
* $Id: FilterDispatcher.java 674498 2008-07-07 14:10:42Z mrdon $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.dispatcher;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.RequestUtils;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.dispatcher.mapper.ActionMapper;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;
import org.apache.struts2.util.ClassLoaderUtils;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
/**
* Master filter for Struts that handles four distinct
* responsibilities:
*
*
createDispatcher()
method could be overriden by /**
* Provide a logging instance.
*/
private Logger log;
/**
* Provide ActionMapper instance, set by injection.
*/
private ActionMapper actionMapper;
/**
* Provide FilterConfig instance, set on init.
*/
private FilterConfig filterConfig;
/**
* Expose Dispatcher instance to subclass.
*/
protected Dispatcher dispatcher;
/**
* Loads stattic resources, set by injection
*/
protected StaticContentLoader staticResourceLoader;
/**
* Initializes the filter by creating a default dispatcher
* and setting the default packages for static resources.
*
* @param filterConfig The filter configuration
*/
public void init(FilterConfig filterConfig) throws ServletException {
try {
this.filterConfig = filterConfig;
initLogging();
dispatcher = createDispatcher(filterConfig);
dispatcher.init();
dispatcher.getContainer().inject(this);
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
} finally {
ActionContext.setContext(null);
}
}
private void initLogging() {
String factoryName = filterConfig.getInitParameter("loggerFactory");
if (factoryName != null) {
try {
Class cls = ClassLoaderUtils.loadClass(factoryName, this.getClass());
LoggerFactory fac = (LoggerFactory) cls.newInstance();
LoggerFactory.setLoggerFactory(fac);
} catch (InstantiationException e) {
System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default");
e.printStackTrace();
} catch (IllegalAccessException e) {
System.err.println("Unable to access logger factory: " + factoryName + ", using default");
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.err.println("Unable to locate logger factory class: " + factoryName + ", using default");
e.printStackTrace();
}
}
log = LoggerFactory.getLogger(FilterDispatcher.class);
}
/**
* Calls dispatcher.cleanup,
* which in turn releases local threads and destroys any DispatchListeners.
*
* @see javax.servlet.Filter#destroy()
*/
public void destroy() {
if (dispatcher == null) {
log.warn("something is seriously wrong, Dispatcher is not initialized (null) ");
} else {
try {
dispatcher.cleanup();
} finally {
ActionContext.setContext(null);
}
}
}
/**
* Create a default {@link Dispatcher} that subclasses can override
* with a custom Dispatcher, if needed.
*
* @param filterConfig Our FilterConfig
* @return Initialized Dispatcher
*/
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
Map
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
/**
* Modify state of StrutsConstants.STRUTS_STATIC_CONTENT_LOADER setting.
* @param staticResourceLoader val New setting
*/
@Inject
public void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {
this.staticResourceLoader = staticResourceLoader;
}
/**
* Modify ActionMapper instance.
* @param mapper New instance
*/
@Inject
public void setActionMapper(ActionMapper mapper) {
actionMapper = mapper;
}
/**
* Provide a workaround for some versions of WebLogic.
*
/**
* Expose the FilterConfig instance.
*
* @return Our FilterConfit instance
*/
protected FilterConfig getFilterConfig() {
return filterConfig;
}
/**
* Wrap and return the given request, if needed, so as to to transparently
* handle multipart data as a wrapped class around the given request.
*
* @param request Our ServletRequest object
* @param response Our ServerResponse object
* @return Wrapped HttpServletRequest object
* @throws ServletException on any error
*/
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {
Dispatcher du = Dispatcher.getInstance();
// Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be
// configured first before struts2 dispatcher filter, hence when its cleanup filter's turn,
// static instance of Dispatcher should be null.
if (du == null) {
Dispatcher.setInstance(dispatcher);
// prepare the request no matter what - this ensures that the proper character encoding
// is used before invoking the mapper (see WW-9127)
dispatcher.prepare(request, response);
} else {
dispatcher = du;
}
try {
// Wrap request first, just in case it is multipart/form-data
// parameters might not be accessible through before encoding (ww-1278)
request = dispatcher.wrapRequest(request, getServletContext());
} catch (IOException e) {
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
log.error(message, e);
throw new ServletException(message, e);
}
return request;
}
/**
* Process an action or handle a request a static resource.
*
// FIXME: this should be refactored better to not duplicate work with the action invocation
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
ActionContext ctx = new ActionContext(stack.getContext());
ActionContext.setContext(ctx);
UtilTimerStack.push(timerKey);
request = prepareDispatcherAndWrapRequest(request, response);
ActionMapping mapping;
try {
mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
} catch (Exception ex) {
log.error("error getting ActionMapping", ex);
dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
return;
}
if (mapping == null) {
// there is no action in this request, should we look for a static resource?
String resourcePath = RequestUtils.getServletPath(request);
if ("".equals(resourcePath) && null != request.getPathInfo()) {
resourcePath = request.getPathInfo();
}
if (staticResourceLoader.canHandle(resourcePath)) {
staticResourceLoader.findStaticResource(resourcePath, request, response);
} else {
// this is a normal request, let it pass through
chain.doFilter(request, response);
}
// The framework did its job here
return;
}
dispatcher.serviceAction(request, response, servletContext, mapping);
} finally {
try {
ActionContextCleanUp.cleanUp(req);
} finally {
UtilTimerStack.pop(timerKey);
}
}
}
}
}