spring mvcソース(二)MultiAction Controller処理プロセス
5016 ワード
spring mvcはコントローラの入り口を提供します.
必要に応じて異なる実装のControllerを提供します.今日は最も一般的なMultiAction Controllerと言います.一つのcontrollerの中で複数の方法が複数の要求に対応します.
1まずMultiAction Controllerの後継関係を見てみます.
2処理要求
Controller処理要求はhandleRequest()方法を呼び出すべきで、Multi Action Controller類にはhandleRequest()方法の具体的な実現がないので、親類AbstractController内のhandleRequest()方法を使用して、具体的に下記のように実現する.
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
必要に応じて異なる実装のControllerを提供します.今日は最も一般的なMultiAction Controllerと言います.一つのcontrollerの中で複数の方法が複数の要求に対応します.
1まずMultiAction Controllerの後継関係を見てみます.
public class MultiActionController extends AbstractController implements LastModified {}
MultiAction ControllerはAbstractControllerを引き継いだ.public abstract class AbstractController extends WebContentGenerator implements Controller {}
AbstractControllerがControllerを実現しました.2処理要求
Controller処理要求はhandleRequest()方法を呼び出すべきで、Multi Action Controller類にはhandleRequest()方法の具体的な実現がないので、親類AbstractController内のhandleRequest()方法を使用して、具体的に下記のように実現する.
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Delegate to WebContentGenerator for checking and preparing.
//
checkAndPrepare(request, response, this instanceof LastModified);
// Execute handleRequestInternal in synchronized block if required.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
return handleRequestInternal(request, response);
}
}
}
return handleRequestInternal(request, response);
}
//
protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception;
上のコードから分かるように、父の種類のAbstractControllerの中のhandleRequest()の方法は完全な方法ではなく、要求を具体的に処理する方法はhandlerequest Internal()はサブクラスで実現します.だから、MultiAction Controllerでhandlequest Internalを探します. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
throws Exception {
try {
//
String methodName = this.methodNameResolver.getHandlerMethodName(request);
//
return invokeNamedMethod(methodName, request, response);
}
catch (NoSuchRequestHandlingMethodException ex) {
return handleNoSuchRequestHandlingMethod(ex, request, response);
}
}
上記の方法の論理:methodNameResoloverを使用して、対応する方法名を要求し、方法を呼び出し、方法の具体的な実現は以下の通りである. protected final ModelAndView invokeNamedMethod(
String methodName, HttpServletRequest request, HttpServletResponse response) throws Exception {
//
Method method = this.handlerMethodMap.get(methodName);
if (method == null) {
throw new NoSuchRequestHandlingMethodException(methodName, getClass());
}
// , request, response, session
try {
Class[] paramTypes = method.getParameterTypes();
List<Object> params = new ArrayList<Object>(4);
params.add(request);
params.add(response);
if (paramTypes.length >= 3 && paramTypes[2].equals(HttpSession.class)) {
HttpSession session = request.getSession(false);
if (session == null) {
throw new HttpSessionRequiredException(
"Pre-existing session required for handler method '" + methodName + "'");
}
params.add(session);
}
// If last parameter isn't of HttpSession type, it's a command.
if (paramTypes.length >= 3 &&
!paramTypes[paramTypes.length - 1].equals(HttpSession.class)) {
Object command = newCommandObject(paramTypes[paramTypes.length - 1]);
params.add(command);
bind(request, command);
}
//
Object returnValue = method.invoke(this.delegate, params.toArray(new Object[params.size()]));
return massageReturnValueIfNecessary(returnValue);
}
catch (InvocationTargetException ex) {
// The handler method threw an exception.
return handleException(request, response, ex.getTargetException());
}
catch (Exception ex) {
// The binding process threw an exception.
return handleException(request, response, ex);
}
}
このようなプロセスを通して、spring mvc解析要求を行い、対応する処理要求を見つけ、その後、パラメータを呼び出して対応方法を呼び出し、要求全体の処理を完了する.あるcontrollerは一つの要求しか処理できません.MultiAction Controllerは複数を実現できます.つまり、handleRequest Internal()が具体的に異なる実現をするからです.私たちが自分のcontrollerを実現するには、Multi Action Controllerを引き継いで方法を実現すればいいです.