basecallmarshaller.java
来自「反向的AJAX。最大的特性是我们成为反向的Ajax。DWR1.x允许你用java」· Java 代码 · 共 577 行 · 第 1/2 页
JAVA
577 行
/* * Copyright 2005 Joe Walker * * Licensed 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.directwebremoting.dwrp;import java.io.IOException;import java.io.PrintWriter;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.directwebremoting.ScriptBuffer;import org.directwebremoting.WebContext;import org.directwebremoting.WebContextFactory;import org.directwebremoting.extend.AccessControl;import org.directwebremoting.extend.Call;import org.directwebremoting.extend.Calls;import org.directwebremoting.extend.ConverterManager;import org.directwebremoting.extend.Creator;import org.directwebremoting.extend.CreatorManager;import org.directwebremoting.extend.InboundContext;import org.directwebremoting.extend.InboundVariable;import org.directwebremoting.extend.MarshallException;import org.directwebremoting.extend.Marshaller;import org.directwebremoting.extend.PageNormalizer;import org.directwebremoting.extend.RealScriptSession;import org.directwebremoting.extend.EnginePrivate;import org.directwebremoting.extend.Replies;import org.directwebremoting.extend.Reply;import org.directwebremoting.extend.ScriptBufferUtil;import org.directwebremoting.extend.ScriptConduit;import org.directwebremoting.extend.ServerException;import org.directwebremoting.extend.TypeHintContext;import org.directwebremoting.util.DebuggingPrintWriter;import org.directwebremoting.util.Logger;import org.directwebremoting.util.Messages;/** * A Marshaller that output plain Javascript. * This marshaller can be tweaked to output Javascript in an HTML context. * This class works in concert with CallScriptConduit, they should be * considered closely related and it is important to understand what one does * while editing the other. * @author Joe Walker [joe at getahead dot ltd dot uk] */public abstract class BaseCallMarshaller implements Marshaller{ /* (non-Javadoc) * @see org.directwebremoting.extend.Marshaller#marshallInbound(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public Calls marshallInbound(HttpServletRequest request, HttpServletResponse response) throws IOException, ServerException { // We must parse the parameters before we setup the conduit because it's // only after doing this that we know the scriptSessionId WebContext webContext = WebContextFactory.get(); Batch batch = (Batch) request.getAttribute(ATTRIBUTE_BATCH); if (batch == null) { batch = new Batch(request, crossDomainSessionSecurity, allowGetForSafariButMakeForgeryEasier, sessionCookieName); // Save calls for retry exception request.setAttribute(ATTRIBUTE_BATCH, batch); } // Various bits of the Batch need to be stashed away places storeParsedRequest(request, webContext, batch); Calls calls = batch.getCalls(); // Debug the environment if (log.isDebugEnabled() && calls.getCallCount() > 0) { // We can just use 0 because they are all shared InboundContext inctx = (InboundContext) batch.getInboundContexts().get(0); StringBuffer buffer = new StringBuffer(); for (Iterator it = inctx.getInboundVariableNames(); it.hasNext();) { String key = (String) it.next(); InboundVariable value = inctx.getInboundVariable(key); if (key.startsWith(ProtocolConstants.INBOUND_CALLNUM_PREFIX) && key.indexOf(ProtocolConstants.INBOUND_CALLNUM_SUFFIX + ProtocolConstants.INBOUND_KEY_ENV) != -1) { buffer.append(key); buffer.append('='); buffer.append(value.toString()); buffer.append(", "); } } if (buffer.length() > 0) { log.debug("Environment: " + buffer.toString()); } } callLoop: for (int callNum = 0; callNum < calls.getCallCount(); callNum++) { Call call = calls.getCall(callNum); InboundContext inctx = (InboundContext) batch.getInboundContexts().get(callNum); // Get a list of the available matching methods with the coerced // parameters that we will use to call it if we choose to use // that method. Creator creator = creatorManager.getCreator(call.getScriptName()); // Which method are we using? Method method = findMethod(call, inctx); if (method == null) { String name = call.getScriptName() + '.' + call.getMethodName(); String error = Messages.getString("BaseCallMarshaller.UnknownMethod", name); log.warn("Marshalling exception: " + error); call.setMethod(null); call.setParameters(null); call.setException(new IllegalArgumentException(error)); continue callLoop; } call.setMethod(method); // Check this method is accessible accessControl.assertExecutionIsPossible(creator, call.getScriptName(), method); // Convert all the parameters to the correct types Object[] params = new Object[method.getParameterTypes().length]; for (int j = 0; j < method.getParameterTypes().length; j++) { try { Class paramType = method.getParameterTypes()[j]; InboundVariable param = inctx.getParameter(callNum, j); TypeHintContext incc = new TypeHintContext(converterManager, method, j); params[j] = converterManager.convertInbound(paramType, param, inctx, incc); } catch (MarshallException ex) { log.warn("Marshalling exception", ex); call.setMethod(null); call.setParameters(null); call.setException(ex); continue callLoop; } } call.setParameters(params); } return calls; } /** * Build a Batch and put it in the request * @param request Where we store the parsed data * @param webContext We need to notify others of some of the data we find * @param batch The parsed data to store */ private void storeParsedRequest(HttpServletRequest request, WebContext webContext, Batch batch) { String normalizedPage = pageNormalizer.normalizePage(batch.getPage()); webContext.setCurrentPageInformation(normalizedPage, batch.getScriptSessionId()); // Remaining parameters get put into the request for later consumption Map paramMap = batch.getSpareParameters(); if (paramMap.size() != 0) { for (Iterator it = paramMap.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); request.setAttribute(key, value); log.debug("Moved param to request: " + key + "=" + value); } } } /** * Find the method the best matches the method name and parameters * @param call The function call we are going to make * @param inctx The data conversion context * @return A matching method, or null if one was not found. */ private Method findMethod(Call call, InboundContext inctx) { if (call.getScriptName() == null) { throw new IllegalArgumentException(Messages.getString("BaseCallMarshaller.MissingClassParam")); } if (call.getMethodName() == null) { throw new IllegalArgumentException(Messages.getString("BaseCallMarshaller.MissingMethodParam")); } Creator creator = creatorManager.getCreator(call.getScriptName()); Method[] methods = creator.getType().getMethods(); List available = new ArrayList(); methods: for (int i = 0; i < methods.length; i++) { // Check method name and access if (methods[i].getName().equals(call.getMethodName())) { // Check number of parameters if (methods[i].getParameterTypes().length == inctx.getParameterCount()) { // Clear the previous conversion attempts (the param types // will probably be different) inctx.clearConverted(); // Check parameter types for (int j = 0; j < methods[i].getParameterTypes().length; j++) { Class paramType = methods[i].getParameterTypes()[j]; if (!converterManager.isConvertable(paramType)) { // Give up with this method and try the next continue methods; } } available.add(methods[i]); } } } // Pick a method to call if (available.size() > 1) { log.warn("Warning multiple matching methods. Using first match."); } if (available.isEmpty()) { return null; } // At the moment we are just going to take the first match, for a // later increment we might pick the best implementation return (Method) available.get(0); } /* (non-Javadoc) * @see org.directwebremoting.Marshaller#marshallOutbound(org.directwebremoting.Replies, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void marshallOutbound(Replies replies, HttpServletRequest request, HttpServletResponse response) throws IOException { // Get the output stream and setup the mimetype response.setContentType(getOutboundMimeType()); PrintWriter out; if (log.isDebugEnabled()) { // This might be considered evil - altering the program flow // depending on the log status, however DebuggingPrintWriter is // very thin and only about logging out = new DebuggingPrintWriter("", response.getWriter()); } else { out = response.getWriter(); } // The conduit to pass on reverse ajax scripts
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?