Sping MVC不运用任何注解处置惩罚(jQuery)Ajax要求(基于XML设置)
2019-11-18杂谈搜奇网40°c
A+ A-1. Spring
Spring框架是一个轻量级的处理方案,是一个潜伏的一站式市肆,用于构建企业停当的运用顺序。Spring框架是一个Java平台,为开辟Java运用顺序供应周全的基础架构支撑。Spring处置惩罚基础构造,因而您可以专注于运用顺序。Spring使您可以从“平常的Java对象”(POJO)构建运用顺序,并将企业效劳非侵入性地运用于POJO。此功用适用于Java SE编程模子以及悉数和部份Java EE。然则,Spring是模块化的,许可您仅运用所需的那些部份,而没必要引入其他部份。您可以将IoC容器与顶部的任何Web框架一同运用,但也可以仅运用 Hibernate集成代码或JDBC笼统层。Spring框架支撑声明式事务治理,经由历程RMI或Web效劳对逻辑的长途接见以及用于耐久化数据的种种选项。它供应了功用周全的MVC框架,并使您可以将AOP透明地集成到软件中。Spring被设想为非侵入式的,这意味着您的域逻辑代码平常不依靠于框架自身。在您的集成层(比方数据接见层)中,将存在对数据接见手艺和Spring库的某些依靠关联。然则,将这些依靠项与其他代码库断绝起来应当很轻易。Spring的两大中心特征:IoC(控制反转),AOP(面向切面编程)。IoC作用:把对象的控制权交给容器治理。AOP作用:面向切面编程(比方日记打印),底层运用动态代办完成。Spring框架包含构造为约20个模块的功用。这些模块分为中心容器,数据接见/集成,Web,AOP(面向方面的编程),检测,音讯通报和测试。Spring的全部完整框 架来讲,其设想准绳则是"对扩大开放,对修正闭合"(OOP设想准绳)。固然Spring另有很多壮大的功用,这里先简朴引见一下,点到为止。
2. Spring MVC
Spring MVC是基于Servlet API构建的原始web框架,从一最先就已包含在就包含在Spring框架中,与Spring框架无缝对接。全称应当为Spring Web MVC,其来源于模块spring-webmvc。然则,平常我们叫它Spring MVC(习气)。Spring MVC框架是缭绕一个 DispatcherServlet (中心控制器)来设想的,这个 Servlet会把要求分发给各个处置惩罚器,并支撑可设置的处置惩罚器映照、视图衬着、当地化、时区 与主题衬着等,以至还能支撑文件上传。"对扩大开放"是Spring Web MVC框架一个重要的设想准绳。Spring Web MVC中心类库中的一些要领被定义为 final 要领。Sp'ring MVC的数据绑定非常天真轻易,视图剖析也设想的非常天真与轻易,而且供应了很多功用壮大的注解机制。固然,Spring MVC的壮大的处所不是一两句话可以搞定的,我们应当参考其文档,而且深切进修研讨,最好研讨研讨源码。这里话不多说,点到为止。
3. Spring MVC处置惩罚(jQuery)Ajax要求(前台不发送数据,背景返回平常字符串)
开辟环境:Eclipse+Tomcat+Spring MVC+Jackson+JSP+jQuery+Ajax
本篇博客比较长,原本是一个小的demo,写这么长不值,不,我以为值,由于我以为本身写的还可以(哈哈!装一波),这些都是笔者一字一句写的,固然有参考一些东西(本人最憎恶复制粘贴),加上本身的明白,涉及到代码完整仔细实践过,本身从头至尾写一遍,也是对本身学问的积聚以及履历的提拔,Spring MVC文档和Spring文档等,请人人仔细看下去,看完这篇,你不仅控制了Ajax,认识了Spring的长处,还会熟知Spring MVC的实行流程,还会接触到风趣的日记打印。固然也可以免费猎取jar包(有源码链接),百度都有(基础都免费)。所以平常的一些jar包都是免费的,没有必要花一些价值去活得开辟包。实质来讲,框架只是个模板,我们顺从框架的范例来开辟就好了,毕竟运用一些框架是我们的开辟变得简朴高效,笔者以为照样应当相识一下底层中心的原理比较好,如许便于在我们开辟的时刻碰到bug的时刻可以敏捷做出决议计划和处理。写博客,我是仔细的。
(1)搭建环境
Eclipse中新建Java Web项目,并把项目布置到Tomcat容器中。下面是项目的构造:
项目基础构造很简朴,没啥可说的。这里说一下lib内里的jar包。既然我们想运用Spring MVC举行开辟,必需导入其开辟包。上面说了,Spring MVC现实上是集成在Spring中的,所以也是导入Spring开辟包。本次运用spring-framework-4.0.0.RELEASE开辟包。
Spring开辟包:spring-aop面向切面编程所用到的包。spring-aspects供应对AspectJ(面向切面的一个框架)的支撑,spring-beans包含接见设置文件,建立和治理Bean以及举行控制反转和依靠注入操纵相干的一切类。spring-core是Spring的中心包(中心东西类)。spring-expression是Spring的表达式言语,spring-jdbc它包含了spring 与 JDBC 数据接见时举行封装的一切类,供应运用springjdbc的最好完成(运用jdbc template)。spring-orm是Spring对DAO特征举行扩大,支撑一些ORM(对象关联映照)框架(比方MyBatis和Hibernate等)。spring-test供应了对Junit等测试框架的简朴封装,这让我们在对Spring的代码举行测试时越发轻易和疾速。spring-tx包为JDBC、Hibernate、JDO、JPA等供应了一致的声明式的编程式事物治理。spring-web包含web运用研发时用到Spring框架时所须要的的中心类。spring-webmvc包含了Spring webmvc框架相干的一切类。
log4j日记信息包。不导这个包的话会报错。
Jasckson三个包(前几篇博客说过很多遍)。这里导入Jackson包的缘由说一下。1. Spring MVC内置的json与对象转换器依靠于Jackson类库。(底层经由历程对Jackson的一些要领举行封装完成)。2. 简朴好用我以为,效力也还可以。固然也可以完成本身的json与对象的转换器(题外话)。
com.springsource三个jar包,重假如为了供应Spring对Apache的一些效劳的支撑。Tomcat就是Apache的,不导这3个包的话会报错。固然,这里只是导入了spring的一部份常常使用的包,另有其他的(本身百度下spring开辟包,在内里找找),本次开辟也没把这些spring包悉数用到,重假如为了偏重引见一下。好了,jar包说完了。下面举行开辟。这里不运用任何注解的目的说一下,只是基于XML设置完成。实在我们运用注解会简朴轻易很多(背面会有更新的),此篇文章重假如为了便于人人熟习Spring MVC的实行流程,并运用它最最原始的一些设置以及要领。轻易人人相识更深条理的东西,以及深切相识Spring MVC一些中心的东西。由于我们天天运用注解,然则预计我们都没相识过注解的机制以及原理,注解有什么用。以及注解替代了那些我们之前开辟比较冗杂的操纵以及要领。有时刻我们研讨一些东西,不能只停留在外表会运用就好了,我们深切究竟层的话会有意想不到的收成及明白。
(2)编写jsp文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html> <html> <head> <base href="<%=basePath%>"> <title>I LOVE YOU</title> <link rel="stylesheet" type="text/css" href=""> <script type="text/javascript" src="index.js"></script> <script type="text/javascript" src="jquery-3.2.1.min.js"></script> </head> <body> <button id="mybutton1" value="springmvc处置惩罚ajax要求" onclick="fun1()" >(jquery)ajax要求(不发送数据)</button> <spand id="show1" /> <br/> <hr/> </body>
很简朴,定义了一个按钮。并挪用js文件相干的函数举行处置惩罚,<span>标签是为了显现内容。页面引入自定义的js文件和jQeury的js文件(注重称号和途径)。
(3)编写js文件
/** * */ //运用jquery提交ajax要求(不照顾数据) function fun1(){ $.ajax({ type:"POST", //发送体式格局 url:"UserController1", //要求地点 data:"", //数据为空 success:function(data){ //胜利后的回调函数 $("#show1").html(data); //页面展现内容 } }); }
很简朴,就写了一个fun1()函数。用来响应按钮。虽然说,议论客户端不发送数据没多大意义,这里我们照样议论一下吧。在进修java基础的时刻,我们还常常议论"空"呢。不是吗?这里重假如为了熟习一下代码实行的流程,毕竟我们进修的历程是由浅入深的。闲话少叙。
(4)编写controller类
package com.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.HttpRequestHandler; public class UserController1 implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); String str = "我是一个 springmvc"; try { response.getWriter().print(str); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
这里定义了一个controller类,而且完成了HttpRequestHandler接口,并完成接口中的笼统要领。要领中定义了一个字符串,运用response猎取打印流举行输出即可。Spring MVC中。平常在我们编写controller(也就是一个handler,用来处置惩罚客户端的要求),要能被Sping MVC辨认它是一个controller类,由于这里没有用到注解。所以我们有2种要领。
第一种:编写controller类,完成org.springframework.web.servlet.mvc.Controller接口,然后交给中心控制器挪用相对应的处置惩罚器适配器举行处置惩罚。不过,完成了Controller,就必需完成个中的笼统要领public abstract ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)。这个要领必需返回一个ModelAndView对象,而我们所作的是对字符串数据和json数据的处置惩罚。所以在这里我们并没有挑选完成Controller接口。
第二种:编写controller类,完成org.springframework.web.HttpRequestHandler接口,然后交给中心控制器挪用响应的处置惩罚器适配器举行处置惩罚,并完成个中的笼统要领。本身可以百度一下Spring MVC的实行流程,这里不多说。
public abstract void handleRequest(HttpServletRequest request, HttpServletResponse response) 我们注重到,这个要领是没有返回值的,所以就轻易了我们对字符串数据和json数据的处置惩罚。注重到有2个参数request和response(这是Servlet的东西)。Spring MVC支撑的支撑的参数范例:
HttpServletRequest 对象,HttpServletResponse 对象,HttpSession 对象,Model/ModelMap 对象。这里我们用到了个中的2个。
(5)设置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>MySpringMVCAjax</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 设置springmvc中心控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 对静态资本举行放行 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/static/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <!-- 设置编码过滤器 --> <filter> <filter-name>SpringCharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SpringCharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
这里我们设置了三个东西。
第一个,设置Spring中心控制器。Sping MVC中心控制器(前端控制器或中心处置惩罚器)org.springframework.web.servlet.DispatcherServlet,DispatcherServlet 实在就是个 Servlet (它继续自 HttpServlet 基类),一样也须要在你 web运用的 web.xml 设置文件下声明。你须要在 web.xml 文件中把你愿望 DispatcherServlet 处置惩罚的要求映照到对应的URL上去。这就是规范的Java EE Servlet配 置。DispatcherServlet就是一个Sping MVC处置惩罚要求的一个中心处置惩罚器,担任调理处置惩罚器映照器,处置惩罚器适配器以及视图剖析器。设置初始化参数来加载Sping MVC的主设置文件springmvc.xml,这里我们把它放在src目录下。
第二个,给静态资本放行。这里注重一下。我们在中心控制器<url-pattern>标签下设置的是 / ,示意一切接见的url都交给中心控制器去处置惩罚,如许致使有能够加载不到静态资本文件(js,css,img)。处理方法:
第一种:在springmvc.xml文件中设置<mvc:default-servlet-handler /><!-- 示意对一切静态资本举行放行 -->(比较高等的要领)
第二种:对静态资本举行放行,如我们web.xml所示。固然,也可以在spring.xml文件举行放行,语法为:
<resources location="/js/" mapping="/js/**" />
<resources location="/css/" mapping="/css/**" />
<resources location="/images/" mapping="/images/**" />
这里运用web.xml对静态资本举行放行,重假如由于这个要领简朴易懂。背面我会对博客内容举行更新升级,再采用比较高等的要领。
第三种:设置中心控制器时,把<url-pattern>标签设置为 *.do 或许 .action就好了。示意以.do末端的或许以.action末端的URL都由前端控制器DispatcherServlet来剖析。这类要领也可以,然则到时接见途径的时刻要加上这个后缀,看起来不太惬意(有一点强迫症的人应当懂)。固然笔者预计没有吧。笔者只是采用一些简朴说不上高效的要领。
第三个,就是设置spring供应编码过滤器。web.xml设置的编码过滤器为了防备前端传入的中文数据涌现乱码题目,运用Spring供应的编码过滤器来一致编码。设置为UTF-8。固然也可以运用GBK等其他编码。GBK编码体式格局的编码是以中国国情而制造的,在国际上的兼容性不好,这也是为何大多数的网页是运用UTF-8编码而不是GBK。UTF-8长处:兼容ASCII,存储英文文件都是单字节,文件小。在eclipse中把项目的编码也设置为UTF-8,JSP页面中字符编码也设置为UTF-8。浏览器网页字符编码也设置为UTF-8。横竖就是一切UTF-8的模样。做这么多重假如一致编码,处理中文乱码乱码题目。由于之前运用servlet和struts2的时刻,常常涌现中文乱码题目,让人摸不着什么思想。所以。Spring供应的这个编码过滤器就比较轻易好用了。所以说Spring是一个奇异的东西。我们研读一下Spring源码,看看Spring开辟的文档,就可以吸取一些英华(精华)。Spring供应的编码过滤器,org.springframework.web.filter.CharacterEncodingFilter类,注重把途径写准确。初始化参数(也就是编码)encoding为UTF-8。Spring里的字符过滤器CharacterEncodingFilter是针对要求的,forceEncoding=true是意义是指不管客户端要求是不是包含了编码,都用过滤器里的编码来剖析要求。forceEncoding默以为false。forceEncoding为true效果: request.setCharacterEncoding("UTF-8");forceEncoding为false的效果:
request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8")。 <url-pattern>标签设置的/*代表过滤一切要求,从而将编码设置为UTF-8。好了。web.xml到此结束。实在有时刻我们只是开辟一个简朴的小例子demo,看起来很简朴。然则我们要相识底层究竟是怎样完成的。比方Java的底层,JVM(Java虚拟机)用c/c++编写,Java类库用Java言语编写。另有比方native当地要领,其底层实质也是c/c++编写的,Java只是挪用了它的接口。这也就诠释了为何native要领效力平常比较高。那末题目来了,c言语用什么编写的 ? 这个可以自行谷歌或百度,这里不多说。固然,一个项目或许事情的实行流程我们也必需熟知。此次开辟看起来很简朴,然则我们把涉及到的学问内容都邑为人人仔细解说,而且都是本人一字一句经由琢磨实践举行编写的。固然,本人也是菜鸟一枚。学问有限。然则我们可以经由进修来猎取更多的学问,提拔本身的才能,从而到达人生的顶峰。不多说了(跑题了,哈哈!)。
(6)设置springmvc.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 设置user实体类 --> <bean id="user" class="com.pojo.User" /> <!-- 设置handler--> <bean name="/UserController1" class="com.controller.UserController1" /> <bean name="/UserController2" class="com.controller.UserController2" /> <bean name="/UserController3" class="com.controller.UserController3" /> <!-- 设置处置惩罚器映照器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <!-- 设置处置惩罚器适配器 --> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/> <!-- 设置json与对象的转换器 --> <bean id="myconverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> <!-- 设置视图剖析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
springmvc.xml是本次开辟的主设置文件。经由历程视察得知,顶层标签<beans>包含了很多bean模块。Spring Bean实在就是是被实例的,组装的及被Spring 容器治理的Java对象。一个bean相称于一个实体类对象,经由历程IoC(控制反转,也叫依靠注入)我们可以把bean注入到容器当中,交给Spring容器治理(比方bean的实例化)。如许做的目的实在解耦合。由于软件设想的准绳就是高内聚,低耦合。Spring默许的bean实例是单例的,我们可以用scope属性来设置bean的作用域。scope可以接收Singleton(单例情势,每次猎取bean只要一个实例)、prototype(原型情势,每次猎取bean都邑发生新的实例)、request(每次HTTP request要求都邑发生差别的Bean实例)、session(每次HTTP session要求都邑发生差别的Bean实例)、global session (每一个全局的HTTPSession对应一个Bean实例。仅在portlet Context的时刻才有用。)5个值。我们常常使用单例情势,由于建立对象自身价值比较高,消耗资本,单例的自身也满足我们的需求了。固然我们也可以依据差别的需求设置差别的scope,这本无可厚非。另有,注重一下引入的xsd文件,Spring文件中的援用的xsd文件是用于校验xml文件的花样用的。Spring默许在启动时是要加载XSD文件来考证xml文件的。相称因而束缚文件。这里我们引入了三个xsd文件,spring-beans-xsd包含对bean的诠释。sprng-mvc.xsd包含了对<mvc>等标签的诠释,spring-context.xsd包含对context的诠释,这里我们实在只用到了spring-beans.xsd束缚文件。
我们详细看一下设置了什么东西。
1. 把User实体类注入到容器(下面会贴User类的代码,这里临时还没用到)。相称因而经由历程<bean>标签来装配一个User类,我们就可以经由历程猎取bean来到达猎取User实体对象的目的。设置bean的id(一个bean的唯一标识)和class(类的全包途径 包.类)。
2. 设置controller(也就是handler,处置惩罚客户端要求)。这里我们设置了好三个controller。我们看UserController1(对应上面的要领UserController1)的设置,设置了一个name和class。Spring MVC要辨认要求的url,就是经由历程挪用处置惩罚器映照器猎取到这个name的称号,找到controller类,然后交给处置惩罚器设配器去处置惩罚controller。相称于就是映照途径。注重称号前要加上/ 不然没法辨认。这里我们设置name=”/UserController1“和类名保持一致(为了轻易),固然也可以起其他名字,别忘了/,前台提交的url和此处name的称号要保持一致。class为UserController1的全包类途径。
3. 设置处置惩罚器映照器BeanNameUrlHandlerMapping。不须要指定id,只设置全类途径即可,即class。这个处置惩罚器映照器,将bean的name作为url举行查找,须要在设置Handler时指定bean的 name(url)。
检察spring-webmvc包下面的DispatcherServlet.properties 资本文件:
# Default implementation classes for DispatcherServlet's strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
Spring MVC的处置惩罚器映照器,常常使用的有2个,一个是org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,继续了
AbstractDetectingUrlHandlerMapping笼统类,它又向上继续了AbstractUrlHandlerMapping笼统类,它又向上继续了AbstractHandlerMapping,
AbstractHandlerMapping笼统类完成了HandlerMapping接口。
另一个是org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,继续了AbstractUrlHandlerMapping笼统类,
AbstractUrlHandlerMapping继续了AbstractHandlerMapping笼统类,AbstractHandlerMapping完成了org.springframework.web.servlet.HandlerMapping
接口。视察资本文件发明,BeanNameUrlHandlerMapping是Spring MVC的默许处置惩罚器映照器,这里我们就运用这个。若要运用SimpleUrlHandlerMapping,
我们依据它的语法来就好了。可以如许设置:
bean id="UserController1" class="com.controller.UserController1" /> <!-- 简朴URL设置处置惩罚器映照器 --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/UserController1">UserController1</prop> </props> </property> </bean>
固然这两种处置惩罚器映照器设置可以并存,中心控制器会准确的去推断 url 用哪一个 Handler 去处置惩罚。
注重这个上面资本文件的处置惩罚器映照器DefaultAnnotationHandlerMapping,经由历程检察源码,它已被烧毁了。被扬弃的以为不好受啊。
(预计DefaultAnnotationHandlerMapping的心田是崩溃的)。
4. 设置处置惩罚器适配器。不须要指定id,class为全类途径。中心控制器挪用处置惩罚器映照器找到了Controller类,那末谁来处置惩罚这个Controller呢。那末此时处置惩罚器适配器就闪亮上台了。什么是处置惩罚器适配器呢。且听下回分解,本章完。。。(皮一下)。经由历程视察以上资本文件。我们发明。Spring MVC的处置惩罚器适配器,常常使用的有2个。
一个是org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,一个是org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
这2个类都完成了HandlerAdapter接口。SimpleControllerHandlerAdapter处置惩罚的Handler必需完成Conreoller接口,平常返回一个ModelAndView对象。
HttpRequestHandlerAdapter处置惩罚的Handler必需完成HttpRequestHandler接口,平常用来处置惩罚字符串或许json数据。由于其笼统要领没有返回值。AnnotationMethodHandlerAdapter已烧毁了,不多说。固然两种适配器可以共存,设置差别的映照器找到差别的controller。
Spring MVC默许的处置惩罚器适配器是HttpRequestHandlerAdapter 。
5. 设置视图剖析器。不须要指定id,class为全类途径。我们这里用的是InternalResourceViewResolver,设置它的class途径,注重有2个属性。prefix示意返回视图页面的前缀,suffix示意返回视图页面的后缀。比方平常我们要视图剖析完成后返回一个页面index.jsp时,prefix相称于设置的是其根目录(在哪儿),suffix就是.jsp,如许在我们运用注解举行开辟的时刻,只须要返回一个字符串"index"就好了。上面那样设置,示意在 Handler 中只须要返回在 WebContent根目录下的jsp 文件名就ok了(为了简朴轻易,开辟比较高效)。视图剖析器作用它担任将一个代表逻辑视图名的字符串 (String)映照到现实的视图范例 View 上。经由历程以上资本文件发明。注重HandlerExceptionResolver处置惩罚器非常剖析器。它担任将捕捉的非常映照到差别的视 图上去,另外还支撑更庞杂的非常处置惩罚代码。Spring MVC的视图剖析器这里引见3种:
第一种:运用ViewResolver接口剖析视图
org.springframework.web.servlet.view.InternalResourceViewResolver类,经由历程一连向上继续,完成org.springframework.web.servlet.ViewResolver接口。在现实运用中InternalResourceViewResolver也是运用的最普遍的一个视图剖析器。本次开辟就用的是这个视图剖析器。这个比较常常使用。InternalResourceViewResolver剖析器可以诠释为内部资本视图剖析器。InternalResourceViewResolver会把返回的视图称号都剖析为InternalResourceView对象,InternalResourceView会把Controller处置惩罚器要领返回的模子属性都存放到对应的request属性中,然后经由历程RequestDispatcher在效劳器端把要求forword重定向到目的URL。
接口中的要领:经由历程传来的参数剖析视图,并返回一个View对象。注重Handler类完成Conteoller接口要领时,就返回了一个ModelAndView对象。ModelAndView 是SpringMVC 框架的一个底层对象,包含 Model 和 View。
public abstract interface ViewResolver
{
public abstract View resolveViewName(String paramString, Locale paramLocale)
throws Exception;
}
第二种:运用RequestToViewNameTranslator接口剖析视图。DefaultRequestToViewNameTranslator为这个接口的完成子类。
这个接口定义了一个笼统要领
public abstract interface RequestToViewNameTranslator
{
public abstract String getViewName(HttpServletRequest paramHttpServletRequest)
throws Exception;
}
示意依据request要求返回一个视图称号的字符串。
第三种:运用FlashMapManager接口剖析视图。SessionFlashMapManager为这个接口的完成子类。
FlashMap治理器。它可以存储并取回两次要求之间 的 FlashMap 对象。后者可用于在要求之间通报数据,平常 是在要求重定向的情境下运用。
这个接口定义的要领:本身看看就好了,在这里不做过量引见。
public abstract interface FlashMapManager
{
public abstract FlashMap retrieveAndUpdate(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);
public abstract void saveOutputFlashMap(FlashMap paramFlashMap, HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse);
}
Map一定时用来保留数据的。RedirectView在页面跳转,数据的保留依靠于FlashMap和FlashMapManger,FlashMapManger在容器初始化时被填入,而FlashMap从Manger可以猎取。
5. 设置json与对象的转换器。这里临时用不到。下面会诠释。先跳过。实在Spring MVC内置的json与对象的转换器底层照样用Jasckson类库完成。
(7)设置log4j.properties日记文件
### set log levels ### log4j.rootLogger = INFO , console , D ### console ### log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH\:mm\:ss} [%p]-[%c] %m%n ### log file ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File =../logs/IvaDubboWeb-info.log log4j.appender.D.Append = true log4j.appender.D.Threshold = INFO log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n ### out zhiding log file ### log4j.logger.haha = INFO, haha log4j.additivity.haha = false log4j.appender.haha = org.apache.log4j.DailyRollingFileAppender log4j.appender.haha.File =D:/logs/mylog.log log4j.appender.haha.Append = true log4j.appender.haha.Threshold = INFO log4j.appender.haha.layout = org.apache.log4j.PatternLayout log4j.appender.haha.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n
Log4j简朴引见:
Log4j是Apache的一个开源项目,经由历程运用Log4j,我们可以控制日记信息运送的目的地是控制台、文件、GUI组件,以至是套接口效劳器、NT的事宜纪录器、UNIX Syslog保卫线程等;我们也可以控制每一条日记的输出花样;经由历程定义每一条日记信息的级别,我们可以越发仔细地控制日记的生成历程。Log4j有三个重要的组件:Loggers(纪录器),Appenders (输出源)和Layouts(规划)。这里可简朴明白为日记种别,日记要输出的处所和日记以何种情势输出。综合运用这三个组件可以轻松地纪录信息的范例和级别,并可以在运转时控制日记输出的款式和位置。
1. 设置根logger,日记输出级别为INFO级别。log4j的输出级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL。比INFO级别高的也会打印输出,比INFO低的不会输出。
2. 设置console,在eclipse的控制台打印日记信息。
3. 设置输出到文件。一个是输出到平常性文件中,另一个是输出到我们指定的文件中。很简朴。(笔者对log4j还琢磨了半天,重假如相识日记打印究竟是什么玩艺儿)。
对上面log4j简朴测试一下(注重要导入log4j开辟包和单元测试JUinit包,并把log4j.properties文件放在src目录下)。打印到控制台:
package com.log4j; import org.apache.log4j.Logger; import org.junit.Test; public class Log4jTest { @Test public void test() { // BasicConfigurator.configure(); //自动疾速地运用缺省Log4j环境。 Logger logger = Logger.getLogger(Log4jTest.class); logger.info("log4j"); logger.info("是"); logger.error("什么"); logger.debug("呢"); } }
运转效果:debug级别比INFO低,无输出。
打印日记到指定文件:把要领放在一个类中就好了
@Test public void test1() { // BasicConfigurator.configure(); //自动疾速地运用缺省Log4j环境。 Logger logger = Logger.getLogger("haha"); logger.info("我"); logger.info("要"); logger.info("学"); logger.info("java"); logger.info("哈"); logger.info("哈"); }
运转效果:
(8)运转顺序
启动Tomcat效劳器,在浏览器地点栏上输入:localhost/MySpringAjax/
圆满运转,不做过量诠释。
4. Spring MVC处置惩罚(jQuery)Ajax要求(前台发送key/value数据,背景返回json数据)
(1)编写jsp页面
反复步骤我们一笔带过就好了。比方jar包都已导好了,另有log4j.properties文件,springmvc.xml主设置文件,这些都是项目公用的。这里就不多说了。
<button id="mybutton2" value="springmvc处置惩罚ajax要求" onclick="fun2()" >发送数据花样为key/value的(jquery)ajax要求</button> <spand id="show2" />
(2)编写js页面
//运用jquery提交key/value数据(ajax要求) function fun2(){ $.ajax({ type:"POST", url:"UserController2", data:"username=wly&password=1314520", //key/value数据 success:function(data){ $("#show2").html(data.username+" "+data.password); } }); }
(3)编写User类
package com.pojo; public class User { private String username; private String password; private Integer age; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User [username=" + username + ", password=" + password + ", age=" + age + "]"; } }
这里我们给User类增添了一个age属性,前台发送的照样username和password。(增添age属性重假如为了对User类举行从新的一些操纵,就是轻易我们演示差别的效果)。
(4)设置web.xml文件
上面已设置好了,设置三个东西。1. Spring MVC中心控制器;2. 对静态资本举行放行;3. 设置Spring MVC供应的编码过滤器
(5)设置springmvc.xml文件
上面已设置好了,须要设置的bean有,User实体类,Controller类,处置惩罚器映照器,处置惩罚器适配器,视图剖析器,json与对象的转换器(本次开辟就挪用Spring MVC内置的json与对象的转换器举行举行json数据与对象的转换)。设置json与对象转换器的id(唯一辨认这个bean)和class(全包类途径)。
<!-- 设置json与对象的转换器 --> <bean id="myconverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
这里我们看一下设置的Spring MVC内置的json与对象的转换器,这里我们运用的是MappingJackson2HttpMessageConverter类。我们先引见一下Spring MVC的2个常常使用的音讯转换器。
1. org.springframework.http.converter.json.MappingJackson2HttpMessageConverter音讯转换器类,这个类继续了AbstractHttpMessageConverter<T>笼统类,而这个笼统类完成了package org.springframework.http.converter.HttpMessageConverter<T>接口。我们看一下这个接口的笼统要领。
package org.springframework.http.converter; import java.io.IOException; import java.util.List; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; public abstract interface HttpMessageConverter<T> { public abstract boolean canRead(Class<?> paramClass, MediaType paramMediaType); public abstract boolean canWrite(Class<?> paramClass, MediaType paramMediaType); public abstract List<MediaType> getSupportedMediaTypes(); public abstract T read(Class<? extends T> paramClass, HttpInputMessage paramHttpInputMessage) throws IOException, HttpMessageNotReadableException; public abstract void write(T paramT, MediaType paramMediaType, HttpOutputMessage paramHttpOutputMessage) throws IOException, HttpMessageNotWritableException; } /* Location: F:\eclipseWorkspace\myworkspace\MySpringMVCAjax\WebContent\WEB-INF\lib\spring-web-4.0.0.RELEASE.jar * Qualified Name: org.springframework.http.converter.HttpMessageConverter * Java Class Version: 6 (50.0) * JD-Core Version: 0.7.0.1 */
平常来讲,我们在Spring MVC完成自定义的json与对象的转化器时,就应当完成HttpMessageConverter<T>这个接口。MediaType在收集协定的音讯头内里叫做Content-Type,运用两部份的标识符来一定一个范例,我们用的时刻实在就是为了表明我们传的东西是什么范例。MediaType类就是一个媒体范例,定义了很多静态常量,定义的就是数据的花样。相称于ContentType。静态常量值有application/json,text/html,image/png,application/xml等等。有很多呢。本身去看源码好了。canRead()要领示意检测能不能把json数据转化为java对象,canWrite示意检测能不能把java对象转化为json数据。read()要领用来读,示意把json数据转化为java对象,write要领示意写,把java对象转换为json数据输出。MappingJackson2HttpMessageConverter是HttpMessageConverter<T>的完成子类,先来看一下AbstractHttpMessageConverter<T>笼统类定义的2个重要的笼统要领。完成HttpMessageConverter<T>接口中的read()和write()笼统要领。然则挪用的照样本类定义的2个笼统要领。再交给起子类去完成这2个要领。
/* */ public final T read(Class<? extends T> clazz, HttpInputMessage inputMessage) /* */ throws IOException /* */ { /* 158 */ return readInternal(clazz, inputMessage); /* */ } /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ public final void write(final T t, MediaType contentType, HttpOutputMessage outputMessage) /* */ throws IOException, HttpMessageNotWritableException /* */ { /* 170 */ final HttpHeaders headers = outputMessage.getHeaders(); /* 171 */ if (headers.getContentType() == null) { /* 172 */ if ((contentType == null) || (contentType.isWildcardType()) || (contentType.isWildcardSubtype())) { /* 173 */ contentType = getDefaultContentType(t); /* */ } /* 175 */ if (contentType != null) { /* 176 */ headers.setContentType(contentType); /* */ } /* */ } /* 179 */ if (headers.getContentLength() == -1L) { /* 180 */ Long contentLength = getContentLength(t, headers.getContentType()); /* 181 */ if (contentLength != null) { /* 182 */ headers.setContentLength(contentLength.longValue()); /* */ } /* */ } /* 185 */ if ((outputMessage instanceof StreamingHttpOutputMessage)) { /* 186 */ StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage)outputMessage; /* */ /* */ /* 189 */ streamingOutputMessage.setBody(new StreamingHttpOutputMessage.Body() /* */ { /* */ public void writeTo(final OutputStream outputStream) throws IOException { /* 192 */ AbstractHttpMessageConverter.this.writeInternal(t, new HttpOutputMessage() /* */ { /* */ public OutputStream getBody() throws IOException { /* 195 */ return outputStream; /* */ } /* */ /* */ public HttpHeaders getHeaders() /* */ { /* 200 */ return AbstractHttpMessageConverter.1.this.val$headers; /* */ } /* */ }); /* */ } /* */ }); /* */ } /* */ else { /* 207 */ writeInternal(t, outputMessage); /* 208 */ outputMessage.getBody().flush(); /* */ } /* */ } /* */ /* */ /* */ protected abstract T readInternal(Class<? extends T> paramClass, HttpInputMessage paramHttpInputMessage) /* */ throws IOException, HttpMessageNotReadableException; /* */ /* */ protected abstract void writeInternal(T paramT, HttpOutputMessage paramHttpOutputMessage) /* */ throws IOException, HttpMessageNotWritableException; /* */ }
接下来,MappingJackson2HttpMessageConverter就涌现了,其完成了笼统类定义的要领readInternal()和writeInternal,经由历程视察发明。readInternal()要领其挪用了ObjectMapper(Jackson中心操纵类)的readValue()要领,示意将json字符串转化为java对象。read()要领现实上是本类扩大的一个要领,作用和readInternal一样。writeInternal()要领其挪用了ObjectMapper(Jackson中心操纵类)的writeValue()要领,示意将java对象转化为json字符串。
大众接口HttpInputMessage,扩大HttpMessage,示意HTTP输入音讯,由表头 和可读主体构成。平常由效劳器端的HTTP要求句柄或客户端的HTTP响应句柄完成。其完成子类ServletServerHttpRequest封装了要求头header和要求体body。
大众接口HttpOutputMessage ,扩大HttpMessage示意HTTP输出音讯,由标头 和可写主体构成。平常由客户端的HTTP要求句柄或效劳器端的HTTP响应句柄完成。其完成子类ServletServerHttpResponse相称于封装了响应头和响应体。
/* */ protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) /* */ throws IOException, HttpMessageNotReadableException /* */ { /* 168 */ JavaType javaType = getJavaType(clazz, null); /* 169 */ return readJavaType(javaType, inputMessage); /* */ } /* */ /* */ /* */ public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) /* */ throws IOException, HttpMessageNotReadableException /* */ { /* 176 */ JavaType javaType = getJavaType(type, contextClass); /* 177 */ return readJavaType(javaType, inputMessage); /* */ } /* */ /* */ private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) { /* */ try { /* 182 */ return this.objectMapper.readValue(inputMessage.getBody(), javaType); /* */ } /* */ catch (IOException ex) { /* 185 */ throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex); /* */ } /* */ } /* */ /* */ /* */ protected void writeInternal(Object object, HttpOutputMessage outputMessage) /* */ throws IOException, HttpMessageNotWritableException /* */ { /* 193 */ JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType()); /* */ /* */ /* */ /* */ /* 198 */ JsonGenerator jsonGenerator = this.objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding); /* */ /* */ /* */ /* 202 */ if (this.objectMapper.isEnabled(SerializationFeature.INDENT_OUTPUT)) { /* 203 */ jsonGenerator.useDefaultPrettyPrinter(); /* */ } /* */ try /* */ { /* 207 */ if (this.jsonPrefix != null) { /* 208 */ jsonGenerator.writeRaw(this.jsonPrefix); /* */ } /* 210 */ this.objectMapper.writeValue(jsonGenerator, object); /* */ } /* */ catch (JsonProcessingException ex) { /* 213 */ throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex); /* */ } /* */ } /* */
2. org.springframework.http.converter.StringHttpMessageConverter音讯转换器类,继续了AbstractHttpMessageConverter<String>笼统类,而这个笼统类完成了HttpMessageConverter<T>接口。重要用于以读写字符串。实在就是一个音讯转换器。默许情况下,该转换器支撑一切介质范例(*/*
),并用写Content-Type
的text/plain
。可以经由历程设置supportedMediaTypes该属性来掩盖。原理:经由历程输入和输出流的体式格局举行读和写操纵。
设想哲学:StringHttpMessageConverter的哲学就是:你想要什么范例的数据,我便发送给你该范例的数据。
实在很简朴的原理,比方我愿望接收的数据范例是Accept: application/json;charset=UTF-8,发送的数据范例Content-Type: application/json;charset=UTF-8 固然也要保持一致。相称于以什么花样输入的字符串,就得以响应的花样举行转换。这里要深切相识的话请看详细源码。
(6)设置编写Controller类
package com.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.web.HttpRequestHandler; import com.pojo.User; public class UserController2 implements HttpRequestHandler{ public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); //加载spring.xml文件初始化ApplicationContext ApplicationContext ac = new ClassPathXmlApplicationContext("springmvc.xml"); //获得User类的实例(对象),可以看出IoC(把对象交给容器治理)机制(工场情势+Java反射机制) User user = (User) ac.getBean("user"); //猎取username和password,举行手动封装 String username=request.getParameter("username"); String password=request.getParameter("password"); user.setUsername(username); user.setPassword(password); //猎取音讯转换器MappingJackson2HttpMessageConverter类对象,完成了HttpMessageConverter接口 HttpMessageConverter converter= (HttpMessageConverter) ac.getBean("myconverter"); //猎取媒体范例,传入的是"application/json;charset=UTF-8"这里我们直接new MediaType mediaType=new MediaType(MediaType.APPLICATION_JSON, null); //实例化响应信息类。ServletServerHttpResponse是HttpOutputMessage的完成子类 //这里直接new,假如设置到springmvc内里显得设置文件冗余。 HttpOutputMessage out=new ServletServerHttpResponse(response); converter.write(user, mediaType, out); } }
首先要猎取2个bean,一个是设置的转换器,一个是User类对象。经由历程加载spring.xml初始化Spring的一个运用高低文ApplicationContext对象,挪用要领getBean("id")。我们可以获得bean对象,实在这是经由历程Java反射机制完成的。这个传入的id是我我们spring.xml中所设置的id,注重一定要对应,保持一致。关于猎取Spring Bean另有其他要领,本身可以百度。获得user对象后,手动举行封装。代码都有注解,很轻易明白。MediaType.APPLICATION_JSON是一个静态常量。MediaType类中定义的这个静态常量(另有很多,这里只枚举一个)public static final MediaType APPLICATION_JSON = valueOf("application/json")。HttpOutputMessage封装输出的信息。末了经由历程音讯转换器的write()要领把对象转化为json数据举行输出,响应客户端。
ApplicationContext是一个中心接口,为运用顺序供应设置。在运用顺序运转时,它是只读的,然则假如完成支撑,则可以从新加载。
ApplicationContext供应:
1. 用于接见运用顺序组件的Bean工场要领。继续自ListableBeanFactory。
2.以通用体式格局加载文件资本的才能。从ResourceLoader
接口继续。
3.将事宜宣布给注册的侦听器的才能。从ApplicationEventPublisher接口继续。
4.处理音讯的才能,支撑国际化。从MessageSource接口继续。
5.从父高低文继续。在子女高低文中的定义将一直优先。比方,这意味着全部Web运用顺序都可以运用单个父高低文,而每一个servlet都有其本身的子高低文,该子高低文独立于任何其他servlet的子高低文。
存在题目:这里的User类对象实在末了照样经由历程Spring容器new的实例(反射),完整不必注解的话,怎样自动完成User类对key/value范例数据的封装呢,我们怎样获得user类呢。有一种思绪(深切相识spring mvc的参数绑定机制,这就要又得研讨研讨源码了)。不知道人人另有什么好的方法。迎接交换哈。
(7)运转顺序
5. Spring MVC处置惩罚(jQuery)Ajax要求(前台发送json数据,背景返回json数据)
(1)编写jsp页面
<button id="mybutton3" value="springmvc处置惩罚ajax要求" onclick="fun3()" >发送数据花样为json的(jquery)ajax要求</button> <spand id="show3" /><br/>
(2)编写js文件
//运用jquery提交json数据(ajax要求) function fun3(){ var user={ //相符json数据花样范例的javascript对象 "username":"我是谁", "password":"1314520" }; $.ajax({ type:"POST", url:"UserController3", contentType:"application/json;charset=UTF-8", //发送数据到效劳器时所运用的内容范例 data:JSON.stringify(user), //将javascript对象转化为json字符串 //预期的效劳器响应的数据范例。效劳器返回json字符串。jquery会自动把json转化为js对象 dataType:"json", //相称于挪用JSON.parse(data)要领。此时我们省去即可。 success:function(data){ $("#show3").html(data.username+" "+data.password+" "+data.age); } }); }
打印信息时,我们加了一个age属性注重一下。这里username设置为中文,重要为了测试会不会涌现乱码(看web.xml设置的编码过滤器见效没)。
(3)编写User类
User实体类和上面一样。有3个属性,username,password,age。供应getters和setters要领,toString要领。
(4)设置web.xml
一样
(5)设置springmvc.xml文件
同理
(6)编写Controller类
package com.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.stereotype.Controller; import org.springframework.web.HttpRequestHandler; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.fasterxml.jackson.databind.ObjectMapper; import com.pojo.User; public class UserController3 implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); ////加载spring.xml文件初始化ApplicationContext ApplicationContext ac = new ClassPathXmlApplicationContext("springmvc.xml"); ////猎取音讯转换器MappingJackson2HttpMessageConverter类对象,完成了HttpMessageConverter接口 HttpMessageConverter converter=(HttpMessageConverter) ac.getBean("myconverter"); ////猎取媒体范例,传入的是"application/json;charset=UTF-8"这里我们直接new对象 MediaType mediaType=new MediaType(MediaType.APPLICATION_JSON, null); //要求信息类,封装输入信息 HttpInputMessage in=new ServletServerHttpRequest(request); //响应信息类,封装输出信息 HttpOutputMessage out=new ServletServerHttpResponse(response); //把前台传来传来json数据转化为User对象(read接收的参数:这里可以把json数据转化为User,得益于HttpInputMessage已把要求的信息已封装好了,包含要求头和要求体) User user= (User) converter.read(User.class, in); //设置岁数 user.setAge(666); System.out.println(user); //把User对象转化为json数据输出 converter.write(user, mediaType, out); } }
代码都有注解。很简朴。音讯转换器对象的write()要领读客户端发送的json数据,把json数据转换为User类对象,为何要转换?(轻易我们代码举行操纵和保护。比方我们上岸时,要查数据库看这个user存在不,设置其他属性什么的,比方age。所以是有一定需求的。java言语是面向对象顺序设想言语,一定操纵java对象轻易疾速)。
(7)跑一下顺序
圆满运转,没有涌现乱码,好了,收工。打印出了username,password,age的内容。
6. 明白Spring MVC的实行流程
(1)用户发送要求到Spring MVC中心控制器(DispatcherServlet)。
(2)前端控制器要求 HandlerMapping 查找 Controller,可以依据 xml 设置、注解举行查找。
(3) 处置惩罚器映照器 HandlerMapping 查找完成后向中心控制器返回 Controller。
(4)前端控制器挪用处置惩罚器适配器去实行 Controller。
(5)处置惩罚器适配器实行 Controller。
(6)Controller实行完成后给适配器返回 ModelAndView对象。
(7)处置惩罚器适配器向前端控制器返回 ModelAndView。ModelAndView 是SpringMVC 框架的一个底层对象,包含 Model 和 View。
(8)前端控制器要求试图剖析器去举行视图剖析依据逻辑视图名来剖析真正的视图。
(9)视图剖析器向前端控制器返回 view。
(10)中心控制器举行视图衬着。就是将模子数据(在 ModelAndView 对象中)填充到 request 域
(11)中心控制器向用户响应效果。
7. 总结
(1)导包。不到log4j日记包会涌现毛病,Spring框架支撑log4j日记输出。支撑Apache效劳的包也要导入(com.springresource)。Jackson包导全。Spring开辟基础包。
(2)加载不到静态资本,要对静态资本文件举行放行。
(3)Spring的IoC机制,可以把对象交给容器治理。IoC中心:经由历程设置文件或许是Annonation的体式格局,将完成类注入到挪用者那边去。
IoC完成原理:工场情势+java反射机制。IOC长处:
第一:资本集合治理,完成资本的可设置和易治理。
第二:降低了运用资本两边的依靠水平,也就是我们说的耦合度。
第三:经由历程设置文件,可以做到转变完成类,而不转变任何一个挪用者的代码(IOC)。
(4)本次开辟我们运用到了Spring MVC内置的音讯转换器MappingJackson2HttpMessageConverter(用于java对象与json数据的转换)。其内部完成原理照样运用到了Jackson开辟包,这就是为何要导入Jackson包的缘由。固然,我们也可以直接运用Jackson类库举行java对象与json数据的转换(我的前几篇博客)。这里挪用内置的音讯转换器,轻易人人明白。Spring MVC的实行流程,以及底层究竟是怎样举行java对象与json数据的。固然也可以在Spring MVC自定义本身的音讯转换器类,让其完成HttpMessageConverter<T>接口。
(5)本次开辟的壮大的处所在于没有运用任何Spring的任何注解,基于纯XML设置,走原生情势。轻易人人相识底层的完成原理。
(6)进修的时刻可以多参考Spring和Spring MVC的开辟文档。有不懂的类可以参考Spring API文档。
(7)经由历程本次开辟,发明Spring MVC的长处:Spring MVC与Spring无缝对接,运用简朴,易扩大,天真性比较强,可适配,非侵入,清楚的角色分别,壮大的设置体式格局,可定制的handler mapping和view resolver。固然我以为Spring MVC最好的处所在于供应了非常天真的参数绑定机制和壮大的注解机制。