自己动手写一个spring之MVC_4 写在前面源码 。本文看下如何返回对象以及页面到前端。当前生成页面的方式有两种一种是前后端分离的方式也就是后端返回对象到前端第二种方式是后端将生成好的html页面直接返回到浏览器本文就看下这两种情况。1返回对象我们不能真的就返回一个对象而是要将对象转换为某种格式后返回为了标识方法需要转换后返回定义注解ResponseBody/** * 对象-》string返回 的标记注解 */Target({ElementType.METHOD})Retention(RetentionPolicy.RUNTIME)publicinterfaceResponseBody{}为了完成转换定义接口HttpMessageConverter// com.hc.minispring.web.v6_modelview.converter.HttpMessageConverter/** * 负责将object转换为某种数据格式如jsonxml等并写回客户端的接口类 */publicinterfaceHttpMessageConverter{voidwrite(Objectobj,HttpServletResponseresponse)throwsIOException;}提供实现类DefaultHttpMessageConverterpublicclassDefaultHttpMessageConverterimplementsHttpMessageConverter{StringdefaultContentTypetext/json;charsetUTF-8;StringdefaultCharacterEncodingUTF-8;ObjectMapperobjectMapper;publicObjectMappergetObjectMapper(){returnobjectMapper;}publicvoidsetObjectMapper(ObjectMapperobjectMapper){this.objectMapperobjectMapper;}publicDefaultHttpMessageConverter(){}Overridepublicvoidwrite(Objectobj,HttpServletResponseresponse)throwsIOException{response.setContentType(defaultContentType);response.setCharacterEncoding(defaultCharacterEncoding);writeInternal(obj,response);response.flushBuffer();}privatevoidwriteInternal(Objectobj,HttpServletResponseresponse)throwsIOException{StringsJsonStrthis.objectMapper.writeValuesAsString(obj);PrintWriterpwresponse.getWriter();pw.write(sJsonStr);}}ObjectMapper是一个接口负责将对象转换为特定数据类型定义如下/** * 将object转换为特定数据格式的接口 */publicinterfaceObjectMapper{// 专门为日期格式定义的接口voidsetDateFormat(StringdateFormat);// 专门为数字格式定义的接口voidsetDecimalFormat(StringdecimalFormat);StringwriteValuesAsString(Objectobj);}转json实现类/** * 默认实现类 */publicclassDefaultObjectMapperimplementsObjectMapper{StringdateFormatyyyy-MM-dd;DateTimeFormatterdatetimeFormatterDateTimeFormatter.ofPattern(dateFormat);StringdecimalFormat#,##0.00;DecimalFormatdecimalFormatternewDecimalFormat(decimalFormat);// ...OverridepublicStringwriteValuesAsString(Objectobj){StringsJsonStr{;Class?clzobj.getClass();Field[]fieldsclz.getDeclaredFields();for(Fieldfield:fields){// ...if(sJsonStr.equals({)){sField\name\:\strValue\;}else{sField,\name\:\strValue\;}sJsonStrsField;}sJsonStr};returnsJsonStr;}}2返回页面因为返回页面是需要用户进行定制的为了方便用户的使用定义类ModelAndView来维护页面信息以及页面需要的数据信息// com.hc.minispring.web.v6_modelview.ModelAndView/** * 页面以及页面需要的数据通过该类设置页面信息以及页面需要的数据信息 */publicclassModelAndView{// 页面的逻辑名称privateObjectview;privateMapString,ObjectmodelnewHashMap();publicModelAndView(){}// ...}有了页面的逻辑名称还不够还要能够解析出实际的页面htmljsppdf 等等因此定义接口/** * 负责根据用户指定的viewname解析实际页面地址的接口 */publicinterfaceViewResolver{ViewresolveViewName(StringviewName)throwsException;}实现类publicclassInternalResourceViewResolverimplementsViewResolver{privateClass?viewClassnull;privateStringviewClassName;privateStringprefix;privateStringsuffix;privateStringcontentType;// ...protectedViewbuildView(StringviewName)throwsException{Class?viewClassgetViewClass();Viewview(View)viewClass.newInstance();view.setUrl(getPrefix()viewNamegetSuffix());StringcontentTypegetContentType();view.setContentType(contentType);returnview;}}我们还需要视图渲染的组件负责渲染页面到前端也就是这里的View如下/** * 负责渲染页面 */publicinterfaceView{voidrender(MapString,?model,HttpServletRequestrequest,HttpServletResponseresponse)throwsException;// ...}实现类:/** * jsp视图渲染 */publicclassJstlViewimplementsView{publicstaticfinalStringDEFAULT_CONTENT_TYPEtext/html;charsetISO-8859-1;// ...Overridepublicvoidrender(MapString,?model,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{for(EntryString,?e:model.entrySet()){request.setAttribute(e.getKey(),e.getValue());}request.getRequestDispatcher(getUrl()).forward(request,response);}}接着来修改RequestMappingHandlerAdapter执行方法返回ModelView// com.hc.minispring.web.v4_split_dispatcher.RequestMappingHandlerAdapterpublicclassRequestMappingHandlerAdapterimplementsHandlerAdapter{Override// public void handle(HttpServletRequest request, HttpServletResponse response, Object handler)publicModelAndViewhandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{// handleInternal(request, response, (HandlerMethod) handler);returnhandleInternal(request,response,(HandlerMethod)handler);}// private void handleInternal(HttpServletRequest request, HttpServletResponse response,privateModelAndViewhandleInternal(HttpServletRequestrequest,HttpServletResponseresponse,HandlerMethodhandlerMethod)throwsException{try{returninvokeHandlerMethod(request,response,handlerMethod);}catch(Exceptione){e.printStackTrace();}returnnull;}// private void invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {privateModelAndViewinvokeHandlerMethod(HttpServletRequestrequest,HttpServletResponseresponse,HandlerMethodhandlerMethod)throwsException{// ...ObjectreturnObjinvocableMethod.invoke(handlerMethod.getBean(),methodParamObjs);ModelAndViewmavnull;// 如果是设置responsebody注解则返回json格式if(invocableMethod.isAnnotationPresent(ResponseBody.class)){System.out.println(convert to json and return!);this.messageConverter.write(returnObj,response);// return;}elseif(returnObjinstanceofModelAndView){// 在controller方法中直接返回了modelandview说明用户希望展示某个页面mav(ModelAndView)returnObj;returnmav;}elseif(returnObjinstanceofString){//在controller 中直接返回了string说明用户希望按照某种规则返回某个页面mavnewModelAndView();mav.setViewName((String)returnObj);returnmav;}returnmav;// response.getWriter().append(returnObj.toString());}}修改dispatcherservlet支持渲染页面packagecom.hc.minispring.web.v6_modelview;// ...publicclassDispatcherServletextendsHttpServlet{privatestaticfinallongserialVersionUID1L;publicstaticfinalStringWEB_APPLICATION_CONTEXT_ATTRIBUTEDispatcherServlet.class.getName().CONTEXT;privatestaticfinalStringVIEW_RESOLVER_BEAN_NAMEviewResolver;// ...privateViewResolverviewResolver;Overridepublicvoidinit(ServletConfigconfig)throwsServletException{// ...}protectedvoidRefresh(){// ...initViewResolvers(this.webApplicationContext);}// ...protectedvoidinitViewResolvers(WebApplicationContextwac){try{this.viewResolver(ViewResolver)wac.getBean(VIEW_RESOLVER_BEAN_NAME);}catch(BeansExceptione){e.printStackTrace();}}Overrideprotectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse){request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE,this.webApplicationContext);try{doDispatch(request,response);}catch(Exceptione){// ...}protectedvoiddoDispatch(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{// ...ModelAndViewmavha.handle(processedRequest,response,handlerMethod);this.render(request,response,mav);}protectedvoidrender(HttpServletRequestrequest,HttpServletResponseresponse,ModelAndViewmv)throwsException{if(mvnull){response.getWriter().flush();response.getWriter().close();return;}// 获取逻辑上的目标视图StringsTargetmv.getViewName();// 获取视图需要的数据MapString,ObjectmodelMapmv.getModel();// 通过逻辑的目标视图获取目标视图的渲染器ViewviewresolveViewName(sTarget,modelMap,request);// 执行真正的渲染view.render(modelMap,request,response);}protectedViewresolveViewName(StringviewName,MapString,Objectmodel,HttpServletRequestrequest)throwsException{if(this.viewResolver!null){ViewviewviewResolver.resolveViewName(viewName);if(view!null){returnview;}}returnnull;}}3测试在applicationContext.xml中定义bean?xml version1.0 encodingUTF-8?beansbeanidaserviceclasscom.hc.minispring.web.v5_databind.test.AServiceImpl/beanidwebBindingInitializerclasscom.hc.minispring.web.v5_databind.DateInitializer/beanbeanidmessageConverterclasscom.hc.minispring.web.v6_modelview.converter.DefaultHttpMessageConverterpropertytypecom.hc.minispring.web.v6_modelview.util.ObjectMappernameobjectMapperrefobjectMapper//beanbeanidobjectMapperclasscom.hc.minispring.web.v6_modelview.util.DefaultObjectMapperpropertytypeStringnamedateFormatvalueyyyy/MM/dd/propertytypeStringnamedecimalFormatvalue###.##//beanbeanidhandlerAdapterclasscom.hc.minispring.web.v4_split_dispatcher.RequestMappingHandlerAdapterpropertytypecom.hc.minispring.web.v6_modelview.converter.HttpMessageConverternamemessageConverterrefmessageConverter/!-- property typecom.minis.web.WebBindingInitializer namewebBindingInitializer refwebBindingInitializer/--/beanbeanidviewResolverclasscom.hc.minispring.web.v6_modelview.InternalResourceViewResolverpropertytypeStringnameviewClassNamevaluecom.hc.minispring.web.v6_modelview.JstlView/propertytypeStringnameprefixvalue/jsp//propertytypeStringnamesuffixvalue.jsp//bean/beans定义测试controllerpackagecom.hc.minispring.web.v6_modelview.controller;// ...publicclassHelloController{AutowiredprivateAServiceaservice;RequestMapping(/hello1658)ResponseBody// public String doTest(String name) {publicUserdoTest(/*User user*/){UserusernewUser();user.setAge(45);user.setName(里斯);user.setBirthday(newDate());returnuser;// return aservice.sayHello() -- user;}RequestMapping(/hellojsp)// ResponseBody// public String doTest(String name) {publicStringhellojsp(/*User user*/){returnindex;// return aservice.sayHello() -- user;}}一个返回对象一个返回页面index.jsp,index.jsp如下% page contentTypetext/html;charsetUTF-8 languagejava % html head titleTitle/title /head body index jsp!!!!!!!!!! /body /html启动测试返回对象和页面C:\Users\dell9020curl http://localhost:8080/minispring_Web_exploded/hello1658 {name:里斯,age:45,birthday:2026/07/14} C:\Users\dell9020curl http://localhost:8080/minispring_Web_exploded/hellojsp html head titleTitle/title /head body index jsp!!!!!!!!!! /body /html C:\Users\dell9020写在后面参考文章列表手把手带你写一个 MiniSpring 。

相关新闻

最新新闻

ARM Cortex-M开发板入门:M-K1HSE环境搭建与Hello World实现

ARM Cortex-M开发板入门:M-K1HSE环境搭建与Hello World实现

1. M-K1HSE开发板开箱与环境准备M-K1HSE是一款面向嵌入式开发者的高性能开发板,搭载了基于ARM Cortex-M系列的处理核心,板载丰富的外设接口和调试工具。作为嵌入式开发的"Hello World"入门项目,我们需要先完成开发环境的搭建。1.1 …

2026/7/16 11:36:22
Windows控制台I/O机制与API实战解析

Windows控制台I/O机制与API实战解析

1. Windows控制台I/O机制基础解析控制台输入输出是Windows系统中最基础的交互方式之一,其底层实现涉及多个关键API和模式设置。理解这些机制对于开发命令行工具、系统监控程序等场景至关重要。Windows控制台子系统通过一组精确定义的API函数提供I/O能力,…

2026/7/16 11:36:22
教培机构考公刷题小程序系统开发,降本增效稳续费

教培机构考公刷题小程序系统开发,降本增效稳续费

如今考公、学历提升、各类资格证培训赛道竞争日趋白热化,行业内卷程度持续加剧。学员刷题需求暴涨、考试题型繁杂多变,让众多培训机构陷入两大运营困境:一是老师备课任务繁重,人力成本居高不下;二是学员学习效果无法直…

2026/7/16 11:36:22
C4D进阶实战:巧用布尔运算打造精密电子元件

C4D进阶实战:巧用布尔运算打造精密电子元件

1. 布尔运算在C4D精密建模中的核心价值 我第一次接触C4D布尔运算是在做一个智能手表模型时,当时需要在外壳上挖出精确的传感器开口。传统的手动布线方法花了整整一下午还出现破面,而布尔运算只用五分钟就完成了这个看似复杂的结构。这种"减法思维&q…

2026/7/16 11:36:22
如何通过AlienFX Control打造终极硬件控制引擎:深度解析开源Alienware工具

如何通过AlienFX Control打造终极硬件控制引擎:深度解析开源Alienware工具

如何通过AlienFX Control打造终极硬件控制引擎:深度解析开源Alienware工具 【免费下载链接】alienfx-tools Alienware systems lights, fans, and power control tools and apps 项目地址: https://gitcode.com/gh_mirrors/al/alienfx-tools 你是否厌倦了臃肿…

2026/7/16 11:36:22
前端工程师的转型之路:从焦虑到AI工程师的实战分享(收藏版)

前端工程师的转型之路:从焦虑到AI工程师的实战分享(收藏版)

文章指出,随着AI的发展,前端工程师面临被替代的风险,建议前端工程师不要把全栈当作终点,而应将AI工程师作为职业发展方向。作者分享了从前端工程师转型为AI工程师的经验,强调“AI First”的学习方法,即遇到…

2026/7/16 11:31:22

月新闻