@RestControllerpublicclassHelloController{@PatchMapping("/hello")// above statement is a shortcut for below statement// @RequestMapping(value = "/hello", method = RequestMethod.PATCH)publicResponseDatahello(){returnResponseData.success(null);}@PutMapping("/hello")// above statement is a shortcut for below statement// @RequestMapping(value = "/hello", method = RequestMethod.PUT)publicResponseDatahello2(){returnResponseData.success(null);}}
packagejakarta.servlet.http;publicabstractclassHttpServletextendsGenericServlet{// .../*** Dispatches client requests to the protected service method. There's no need to override this method.* ...*/@Overridepublicvoidservice(ServletRequest req,ServletResponse res)throwsServletException,IOException{HttpServletRequest request;HttpServletResponse response;try{request =(HttpServletRequest) req;response =(HttpServletResponse) res;}catch(ClassCastException e){thrownewServletException(lStrings.getString("http.non_http"));}service(request, response);}// ...protectedvoidservice(HttpServletRequest req,HttpServletResponse resp)throwsServletException,IOException{String method = req.getMethod();if(method.equals(METHOD_GET)){// ..doGet(req, resp);// ...}elseif(method.equals(METHOD_HEAD)){// ..doHead(req, resp);}elseif(method.equals(METHOD_POST)){doPost(req, resp);}elseif(method.equals(METHOD_PUT)){doPut(req, resp);}elseif(method.equals(METHOD_DELETE)){doDelete(req, resp);}elseif(method.equals(METHOD_OPTIONS)){doOptions(req, resp);}elseif(method.equals(METHOD_TRACE)){doTrace(req, resp);}else{// Note that this means NO servlet supports whatever// method was requested, anywhere on this server.}}// ...}
packageorg.springframework.web.servlet;publicabstractclassHttpServletBeanextendsHttpServletimplementsEnvironmentCapable,EnvironmentAware{// ...// no override service(), subclass `FrameworkServlet` will implement this method// ...}
packageorg.springframework.web.servlet;publicabstractclassFrameworkServletextendsHttpServletBeanimplementsApplicationContextAware{// ...privatestaticfinalSet<String>HTTP_SERVLET_METHODS=Set.of("DELETE","HEAD","GET","OPTIONS","POST","PUT","TRACE");// .../*** Override the parent class implementation in order to intercept requests* using PATCH or non-standard HTTP methods (WebDAV).*/@Overrideprotectedvoidservice(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{if(HTTP_SERVLET_METHODS.contains(request.getMethod())){super.service(request, response);}// PATCH is missing, so process will go hereelse{processRequest(request, response);}}// ...@OverrideprotectedfinalvoiddoGet(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{processRequest(request, response);}/*** Delegate POST requests to {@link #processRequest}.* @see #doService*/@OverrideprotectedfinalvoiddoPost(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{processRequest(request, response);}/*** Delegate PUT requests to {@link #processRequest}.* @see #doService*/@OverrideprotectedfinalvoiddoPut(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{processRequest(request, response);}/*** Delegate DELETE requests to {@link #processRequest}.* @see #doService*/@OverrideprotectedfinalvoiddoDelete(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{processRequest(request, response);}/*** Delegate OPTIONS requests to {@link #processRequest}, if desired.* <p>Applies HttpServlet's standard OPTIONS processing otherwise,* and also if there is still no 'Allow' header set after dispatching.* @see #doService*/@OverrideprotectedvoiddoOptions(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{if(this.dispatchOptionsRequest ||CorsUtils.isPreFlightRequest(request)){processRequest(request, response);if(response.containsHeader(HttpHeaders.ALLOW)){// Proper OPTIONS response coming from a handler - we're done.return;}}// Use response wrapper in order to always add PATCH to the allowed methodssuper.doOptions(request,newHttpServletResponseWrapper(response){@OverridepublicvoidsetHeader(String name,String value){if(HttpHeaders.ALLOW.equals(name)){value =(StringUtils.hasLength(value)? value +", ":"")+HttpMethod.PATCH.name();}super.setHeader(name, value);}});}/*** Delegate TRACE requests to {@link #processRequest}, if desired.* <p>Applies HttpServlet's standard TRACE processing otherwise.* @see #doService*/@OverrideprotectedvoiddoTrace(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{if(this.dispatchTraceRequest){processRequest(request, response);if("message/http".equals(response.getContentType())){// Proper TRACE response coming from a handler - we're done.return;}}super.doTrace(request, response);}/*** Process this request, publishing an event regardless of the outcome.* <p>The actual event handling is performed by the abstract* {@link #doService} template method.*/protectedfinalvoidprocessRequest(HttpServletRequest request,HttpServletResponse response)throwsServletException,IOException{long startTime =System.currentTimeMillis();Throwable failureCause =null;LocaleContext previousLocaleContext =LocaleContextHolder.getLocaleContext();LocaleContext localeContext =buildLocaleContext(request);RequestAttributes previousAttributes =RequestContextHolder.getRequestAttributes();ServletRequestAttributes requestAttributes =buildRequestAttributes(request, response, previousAttributes);WebAsyncManager asyncManager =WebAsyncUtils.getAsyncManager(request);asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(),newRequestBindingInterceptor());initContextHolders(request, localeContext, requestAttributes);try{doService(request, response);}catch(ServletException|IOException ex){failureCause = ex;throw ex;}catch(Throwable ex){failureCause = ex;thrownewServletException("Request processing failed: "+ ex, ex);}finally{resetContextHolders(request, previousLocaleContext, previousAttributes);if(requestAttributes !=null){requestAttributes.requestCompleted();}logResult(request, response, failureCause, asyncManager);publishRequestHandledEvent(request, response, startTime, failureCause);}}// ...protectedabstractvoiddoService(HttpServletRequest request,HttpServletResponse response)throwsException;// ...}
packageorg.springframework.web.servlet;publicclassDispatcherServletextendsFrameworkServlet{// ...@OverrideprotectedvoiddoService(HttpServletRequest request,HttpServletResponse response)throwsException{// ...try{doDispatch(request, response);}finally{// ...}// ...}// .../*** Process the actual dispatching to the handler.* The handler will be obtained by applying the servlet's HandlerMappings in order. * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters to find the first that supports the handler class. * All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers themselves to decide which methods are acceptable.*/@SuppressWarnings("deprecation")protectedvoiddoDispatch(HttpServletRequest request,HttpServletResponse response)throwsException{// ...try{// ...try{// ...// Determine handler for the current request.// important heremappedHandler =getHandler(processedRequest);// ...// Determine handler adapter for the current request.HandlerAdapter ha =getHandlerAdapter(mappedHandler.getHandler());// ...// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if(asyncManager.isConcurrentHandlingStarted()){return;}applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}// catch()}//catch()}// .../*** Return the HandlerExecutionChain for this request.* <p>Tries all handler mappings in order.*/@NullableprotectedHandlerExecutionChaingetHandler(HttpServletRequest request)throwsException{if(this.handlerMappings !=null){for(HandlerMapping mapping :this.handlerMappings){HandlerExecutionChain handler = mapping.getHandler(request);if(handler !=null){return handler;}}}returnnull;}// ...}
packageorg.springframework.web.servlet.handler;publicabstractclassAbstractHandlerMappingextendsWebApplicationObjectSupportimplementsHandlerMapping,Ordered,BeanNameAware{// .../*** Look up a handler for the given request, falling back to the default* handler if no specific one is found.* @param request current HTTP request* @return the corresponding handler instance, or the default handler* @see #getHandlerInternal*/@Override@NullablepublicfinalHandlerExecutionChaingetHandler(HttpServletRequest request)throwsException{Object handler =getHandlerzInternal(request);if(handler ==null){handler =getDefaultHandler();}if(handler ==null){returnnull;}// Bean name or resolved handler?if(handler instanceofString handlerName){handler =obtainApplicationContext().getBean(handlerName);}// Ensure presence of cached lookupPath for interceptors and othersif(!ServletRequestPathUtils.hasCachedPath(request)){initLookupPath(request);}HandlerExecutionChain executionChain =getHandlerExecutionChain(handler, request);if(logger.isTraceEnabled()){logger.trace("Mapped to "+ handler);}elseif(logger.isDebugEnabled()&&!DispatcherType.ASYNC.equals(request.getDispatcherType())){logger.debug("Mapped to "+ executionChain.getHandler());}if(hasCorsConfigurationSource(handler)||CorsUtils.isPreFlightRequest(request)){CorsConfiguration config =getCorsConfiguration(handler, request);if(getCorsConfigurationSource()!=null){CorsConfiguration globalConfig =getCorsConfigurationSource().getCorsConfiguration(request);config =(globalConfig !=null? globalConfig.combine(config): config);}if(config !=null){config.validateAllowCredentials();}executionChain =getCorsHandlerExecutionChain(request, executionChain, config);}return executionChain;}// ...}
packageorg.springframework.web.method;publicclassHandlerMethod{// ...publicHandlerMethodcreateWithResolvedBean(){Object handler =this.bean;// default would go hereif(this.bean instanceofString beanName){Assert.state(this.beanFactory !=null,"Cannot resolve bean name without BeanFactory");handler =this.beanFactory.getBean(beanName);}returnnewHandlerMethod(this, handler);}// ...}