赞
踩
目录
1.2、SpringMVC中的核心Servlet – DispatcherServlet
以上 1, 2. 都是项目启动的过程, 没有执行任何的用户请求。
2.2.2 CharacterEncodingFilter使用:
2.2.3 请求中参数名和形参名不一样,使用@RequestParam
来源:动力节点
项目:SpringMVC
处理用户的请求:
SpringMVC三层架构理解:SpringMVC教程 - 动力节点
SpringMVC是管理控制器对象, 原来没有SpringMVC之前使用 Servlet作为控制器对象使用。
现在通过SpringMVC容器创建一种叫做控制器的对象,代替Servlet行驶控制器的角色。
需求:用户提交一个请求,服务端处理器接收该请求后给一条欢迎信息,在相应页面显示该信息。
SpringMVC 主要使用注解的方式, 创建控制器对象, 处理请求:
1、加依赖项:
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.2.5.RELEASE</version>
- </dependency>
-
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>3.0-alpha-1</version>
- </dependency>
加入webmvc后自动导入spring核心依赖:
2、配置web.xml
- <servlet>
- <servlet-name>myweb</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>
- <!--
- 表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
- 数值越小,创建对象的时间越早。
- -->
- <load-on-startup>1</load-on-startup>
- </servlet>
-
-
- <servlet-mapping>
- <servlet-name>myweb</servlet-name>
- <!--
- url-pattern 作用: 把一些请求交给指定的servlet处理
- 使用中央调度器(DispatcherServlet)
- 1. 使用扩展名方式, 格式 *.xxx , xxx是自定义的扩展名。
- 例如 *.do , *.action, *.mvc 等等. 不能使用*.jsp
- http://localhost:8080/myweb/some.do
- http://localhost:8080/myweb/user/list/queryUser.do
- http://localhost:8080/myweb/user/list/list.do
- 2. 使用斜杠 "/"
- -->
- <url-pattern>*.do</url-pattern>
-
- </servlet-mapping>
3、配置tomcat
4、启动tomcat
5、访问 http://localhost:8080/ch01_springmvc/mymvc
- 类型 异常报告
-
- 消息 Servlet[springmvc]的Servlet.init()引发异常
-
- 描述 服务器遇到一个意外的情况,阻止它完成请求。
-
- 例外情况
-
- javax.servlet.ServletException: Servlet[springmvc]的Servlet.init()引发异常
- org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
- org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
- org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
- org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:364)
- org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:624)
- org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
- org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
- org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1650)
- org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
- org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
- org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
- org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
- java.lang.Thread.run(Thread.java:748)
- 根本原因。
-
- org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/springmvc-servlet.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/springmvc-servlet.xml]
- org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:340)
- org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:305)
- org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
- org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224)
- org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195)
- org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
- org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
- org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:133)
6、问题分析:
1、其中<load-on-startup>1</load-on-startup>的作用是:在容器启动的时候创建DispatcherServlet对象。
2、url-pattern 作用: 把一些请求交给指定的servlet处理 使用中央调度器(前段控制器):DispatcherServlet:
3、配置的自定义配置文件的位置的变量 contextConfigLocation在DispatcherServlet父类 FrameworkServlet中。
- public class DispatcherServlet extends FrameworkServlet {
-
- }
-
-
- public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
- public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
- public static final Class<?> DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
- public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";
- private static final String INIT_PARAM_DELIMITERS = ",; \t\n";
- @Nullable
- private String contextAttribute;
- private Class<?> contextClass;
- @Nullable
- private String contextId;
- @Nullable
- private String namespace;
- @Nullable
- private String contextConfigLocation;
-
- }
- <!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd" >
-
- <web-app>
-
- <!-- 声明springmvc核心对象
- 当访问 mymvc后,报错:文件没有找到,文件是[/WEB-INF/springmvc-servlet.xml]
- 当修改servlet-name为 web时,显示文件没找到,文件是[/WEB-INF/web-servlet.xml]
- 错误原因:
- DispatcherServlet的一个作用就是:
- 在servlet的init方法中,会创建springmvc使用的容器对象WebApplicationContext,
- WebApplicationContext context = new WebApplicationContext(配置文件);
- 且该配置文件的默认路径:/WEB-INF/</servlet-name>-servlet.xml
- 解决方法:一般不使用默认路径,都是 自定义配置文件的位置,见如下:
- -->
- <servlet>
- <servlet-name>springmvc</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!--自定义配置文件的位置
- 原理:DispatcherServlet会读取变量 contextConfigLocation,取出变量的值:
- classpath:springmvc.xml 当作容器的入参WebApplicationContext(classpath:springmvc.xml);
- -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- <!--
- 表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
- 数值越小,创建对象的时间越早。
- -->
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!--
- url-pattern 作用: 把一些请求交给指定的servlet处理
- 使用中央调度器(DispatcherServlet)
- 1. 使用扩展名方式, 格式 *.xxx , xxx是自定义的扩展名。
- 例如 *.do , *.action, *.mvc 等等. 不能使用*.jsp
- http://localhost:8080/myweb/some.do
- http://localhost:8080/myweb/user/list/queryUser.do
- http://localhost:8080/myweb/user/list/list.do
- 2. 使用斜杠 "/"
- -->
- <servlet-mapping>
- <servlet-name>springmvc</servlet-name>
- <url-pattern>/mymvc</url-pattern>
- </servlet-mapping>
-
- </web-app>
DispatcherServlet作用:
1、在Servlet的init()方法中创建springmvc的容器对象 WebApplicationContext。创建springmvc配置文件里的所有java对象,就是controller对象。
2、DispatcherServlet是一个Servlet,能够接受请求。
注意:只有DispatcherServlet可以接收请求,然后将请求交给自定义的各种Controller处理。
用户发起some.do—DispatcherServlet(Servlet接收请求)—转给MyController:
- public class DispatcherServlet extends HttpServlet{
-
- public void service(HttpServletRequest request, HttpServletResponse response){
- if(“some.do”.equals(request.getURI())){
- //从容器中获取MyController
- MyController c = ctx.getBean(“some”));
- c.doSome();
- } else if( “other.do”.equals(request.getURI())){
- OtherController c = ctx.getBean(“other”));
- c.doOther();
- }
- }
-
- }
- <!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd" >
-
- <web-app>
-
- <!-- 声明springmvc核心对象
- 当访问 mymvc后,报错:文件没有找到,文件是[/WEB-INF/springmvc-servlet.xml]
- 当修改servlet-name为 web时,显示文件没找到,文件是[/WEB-INF/web-servlet.xml]
- 错误原因:
- DispatcherServlet的一个作用就是:
- 在servlet的init方法中,会创建springmvc使用的容器对象WebApplicationContext,
- WebApplicationContext context = new WebApplicationContext(配置文件);
- 且该配置文件的默认路径:/WEB-INF/</servlet-name>-servlet.xml
- 解决方法:一般不使用默认路径,都是 自定义配置文件的位置,见如下:
- -->
- <servlet>
- <servlet-name>myweb</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!--自定义配置文件的位置
- 原理:DispatcherServlet会读取变量 contextConfigLocation,取出变量的值:
- classpath:springmvc.xml 当作容器的入参WebApplicationContext(classpath:springmvc.xml);
- -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:springmvc.xml</param-value>
- </init-param>
- <!--
- 表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
- 数值越小,创建对象的时间越早。
- -->
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!--
- url-pattern 作用: 把一些请求交给指定的servlet处理
- 使用中央调度器(前段控制器):DispatcherServlet:
- 1. 使用扩展名方式, 格式 *.xxx , xxx是自定义的扩展名。
- 例如 *.do , *.action, *.mvc 等等. 不能使用*.jsp
- http://localhost:8080/myweb/some.do
- http://localhost:8080/myweb/user/list/queryUser.do
- http://localhost:8080/myweb/user/list/list.do
- 2. 使用斜杠 "/"
- -->
- <servlet-mapping>
- <servlet-name>myweb</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
-
- </web-app>
- <?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: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/context https://www.springframework.org/schema/context/spring-context.xsd">
-
- <!-- springmvc配置文件 -->
- <!-- 注解扫描 -->
- <context:component-scan base-package="com.crane.springmvc"></context:component-scan>
-
- <!-- 声明视图解析器: 帮助处理视图
- 作用:简化controller中的写法:
- 之前: modelAndView.setViewName("WEB-INF/view/show.jsp");
- 现在: modelAndView.setViewName("show");
- -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!-- 前缀:指定视图文件的路径-->
- <property name="prefix" value="/WEB-INF/view/"></property>
- <!-- 后缀:指定视图文件的扩展名-->
- <property name="suffix" value=".jsp"></property>
- </bean>
- </beans>
3、配置文件的加载顺序和功能
- <servlet>
- <servlet-name>myweb</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>
- <!--
- 表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
- 数值越小,创建对象的时间越早。
- -->
- <load-on-startup>1</load-on-startup>
- </servlet>
根据load-on-startup的值为1,在tomcat启动时会创建DispatcherServlet的对象, 然后执行init()方法。 在init()方法中会执行 springmvc容器对象创建:WebApplicationContext ctx = new ClassPathXmlApplicationContext(“classpath:springmvc.xml”)
- <context:component-scan base-package="com.bjpowernode.controller" />
-
- <!--声明视图解析器:帮助处理视图-->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!--前缀:指定视图文件的路径-->
- <property name="prefix" value="/WEB-INF/view/" />
- <!--后缀:视图文件的扩展名-->
- <property name="suffix" value=".jsp" />
- </bean>
使用组件扫描器base-package=“com.crane.controller” ,遍历controller包中的所有类,MyController类, 找到这个类中的@Controller, @RequestMapping注解, 就能创建MyContoller对象。知道some.do的请求是执行doSome()方法。
3、用户发起请求some.do----DispatcherServlet
DispatcherServlet里面有 WebApplicationContext 。 WebApplicationContext 里面有MyController对象。请求some.do ,DispatcherServlet 就知道是 MyController处理的。
1、用户发起请求给DispatcherServlet。
2、DispatcherServlet把请求(request)交给了 处理器映射器。
处理器映射器: springmvc框架中的对象, 需要实现HandlerMapping接口。
映射器作用: 从springmvc容器中,获取控制器对象(MyController),把找到的控制器和拦截器对象都放到 处理器执行链对象中保存,并返回给中央调度器。(MyController controller = ApplicationContext.getBean())
3、DispatcherServlet把获取到的处理器执行链中的控制器对象,交给了处理器适配器。
处理器适配器:是springmvc框架中的对象, 实现HandlerAdapter接口。
适配器作用: 执行控制器的方法, 也就是执行MyController.doSome()方法。得到结果ModelAndView。
4、DispatcherServlet把控制器执行结果mv交给了 视图解析器
视图解析器: springmvc中的对象,需要实现ViewResolver接口。
视图解析器作用: 处理视图的, 组成视图的完整路径。 能创建View类型的对象。
5、DispatcherServlet调用View类的方法, 把Model中的数据放入到request作用域。 执行request.setAttribute(), 对视图执行forward()转发行为, request.getRequestDispather("/show.jsp").forward(request,response)
- @RequestMapping(value ="/some.do")
- public ModelAndView doSome(){
-
- }
- @RequestMapping(value ="/other.do",method = RequestMethod.POST)
- public ModelAndView doOther(){
-
- }
post: 添加修改,适用参数多时。
get: 查询,适用参数少时,get有缓存当查询的数据长时间不变化使用。
- @RequestMapping(value={ "/other.do","/test/second.do"})
- public ModelAndView doOther(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, HttpSession httpSession){
- System.out.println("执行了 doOther 方法");
- String name = httpServletRequest.getParameter("name");
- System.out.println(name);
-
- }
逐个接收: 请求中的参数名和控制器方法的形参名一样。按照名称对象接收参数:
- <p>逐个接收请求参数</p>
- <form action="receive-property.do" method="post">
- 姓名:<input type="text" name="name"> <br/>
- 年龄:<input type="text" name="age"> <br/>
- <input type="submit" value="提交参数">
- </form>
Controller接收参数:
- @RequestMapping(value ="/receive-property.do")
- public ModelAndView doPropertyParam(String name, Integer age) {
-
- }
接收参数的问题:
逐个接收的原理:
当方法定义必须使用Post请求,而我们使用了get方式请求,则会报错:Method not Allowed:405
解决乱码问题:使用过滤器,框架提供了过滤器:CharacterEncodingFilter。
注意:get不会出现乱码问题,只处理post乱码问题即可。
- 在web.xml 声明过滤器
-
- <!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd" >
-
- <web-app>
-
- <!-- 声明过滤器,框架提供的,解决post请求中乱码问题-->
- <filter>
- <filter-name>characterEncodingFilter</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>
- <!--强制请求(request)对象使用encoding的编码方式-->
- <param-name>forceRequestEncoding</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <!--强制应答(response)对象使用encoding的编码方式-->
- <param-name>forceResponseEncoding</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>characterEncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
-
- <!-- 声明springmvc核心对象
- 当访问 mymvc后,报错:文件没有找到,文件是[/WEB-INF/springmvc-servlet.xml]
- 当修改servlet-name为 web时,显示文件没找到,文件是[/WEB-INF/web-servlet.xml]
- 错误原因:
- DispatcherServlet的一个作用就是:
- 在servlet的init方法中,会创建springmvc使用的容器对象WebApplicationContext,
- WebApplicationContext context = new WebApplicationContext(配置文件);
- 且该配置文件的默认路径:/WEB-INF/</servlet-name>-servlet.xml
- 解决方法:一般不使用默认路径,都是 自定义配置文件的位置,见如下:
- -->
- <servlet>
- <servlet-name>myweb</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!--自定义配置文件的位置
- 原理:DispatcherServlet会读取变量 contextConfigLocation,取出变量的值:
- classpath:springmvc.xml 当作容器的入参WebApplicationContext(classpath:springmvc.xml);
- -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:springmvc.xml</param-value>
- </init-param>
- <!--
- 表示服务器tomcat创建对象的顺序, 是个整数值, 大于等于0.
- 数值越小,创建对象的时间越早。
- -->
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!--
- url-pattern 作用: 把一些请求交给指定的servlet处理
- 使用中央调度器(前段控制器):DispatcherServlet:
- 1. 使用扩展名方式, 格式 *.xxx , xxx是自定义的扩展名。
- 例如 *.do , *.action, *.mvc 等等. 不能使用*.jsp
- http://localhost:8080/myweb/some.do
- http://localhost:8080/myweb/user/list/queryUser.do
- http://localhost:8080/myweb/user/list/list.do
- 2. 使用斜杠 "/"
- -->
- <servlet-mapping>
- <servlet-name>myweb</servlet-name>
- <!--强制所有请求,先经过过滤器处理-->
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
-
-
- </web-app>
form表单中的参数是rname 和 rage,提交给controller的参数方法doReceiveParam形参名称是name 和 age。使用@RequestParam解决。
- <form action="receive-param.do" method="post">
- 姓名:<input type="text" name="rname"><br/>
- 年龄:<input type="text" name="rage"><br/>
- <input type="submit" value="提交">
- </form>
- /**
- * 逐个接收请求参数:请求中参数名和形参名不一样
- * @RequestParam:解决名称不一样的问题
- * 属性:value 请求中的参数名称
- * required:boolean类型,默认是true
- * ture是指请求中必须有此参数,没有则报错
- * 位置:在形参定义的前面
- */
- @RequestMapping(value="/receive-param.do")
- public ModelAndView doReceiveParam(@RequestParam(value="rname") String name,@RequestParam(value="rage") String age){
- System.out.println("执行了 doOther 方法");
- System.out.println(name + ":" + age);
- //调用service对象,处理请求,返回数据
- ModelAndView modelAndView = new ModelAndView();
- //添加数据
- modelAndView.addObject("msg",name);
- modelAndView.addObject("fun",age);
- modelAndView.setViewName("show");
- //返回结果
- return modelAndView;
- }
对象接收: 在控制器方法的形参是java对象, 使用java对象的属性接收请求中参数值。
要求: java对象的属性名和请求中参数名一样。
- <p>对象接收请求参数</p>
- <form action="receive-object.do" method="post">
- 姓名:<input type="text" name="name"><br/>
- 年龄:<input type="text" name="age"><br/>
- <input type="submit" value="对象提交">
- </form>
- public class Student {
- // 属性名和请求中参数名一样
- private String name;
- private Integer age;
- // set| get方法
-
- /**
- * 对象接收: 在控制器方法的形参是java对象, 使用java对象的属性接收请求中参数值。
- * 要求: java对象的属性名和请求中参数名一样。
- * java类中需要有一个无参构造函数,属性有set方法
- * 框架处理:
- * 1、调用Student的无参构造函数,创建对象
- * 2、调用对象的set方法,同名的参数调用对应的set方法
- * 参数是name,调用setName(参数值)
- */
- @RequestMapping(value="/receive-object.do")
- public ModelAndView doReceiveObject(Student student){
- System.out.println("执行了 doOther 方法");
- System.out.println(student.getName() + ":" + student.getAge());
- //调用service对象,处理请求,返回数据
- ModelAndView modelAndView = new ModelAndView();
- //添加数据
- modelAndView.addObject("msg",student.getName() );
- modelAndView.addObject("fun",student.getAge());
- modelAndView.setViewName("show");
- //返回结果
- return modelAndView;
- }
- }
控制器方法的返回值表示本次请求的处理结果,返回值有ModelAndView, String, void , Object
如果要求请求的结果有数据和视图,使用ModelAndView最方便。
框架对返回值是String,执行的是forward转发操作。
- //使用requst是为了让请求的参数name和age在show.jsp中展示。
- @RequestMapping(value ="/return-string-view.do")
- public String doReturnStringView1(HttpServletRequest request,String name, Integer age) {
- System.out.println("执行了MyController的doReturnStringView1方法name=");
- request.setAttribute("myname",name);
- request.setAttribute("myage",age);
- //返回结果,forward,转发到show.jsp
- //逻辑名称, 需要配置视图解析器
- return "show";
- }
-
- @RequestMapping(value ="/return-string-view2.do")
- public String doReturnStringView2(String name, Integer age) {
- System.out.println("执行了MyController的doReturnStringView2方法name=");
- //完整视图路径,不能使用视图解析器
- return "/WEB-INF/view/show.jsp";
- }
void: 没有数据和视图, 可以使用HttpServletResponse对象输出数据,响应ajax请求。使用较少,一般使用Object。
导包:向浏览器返回json格式,使用工具类将字符串转为json格式
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>2.13.1</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.13.0</version>
- </dependency>
对象转json、输出json
- /**
- * 控制器返回void,相应ajax请求,使用HttpServletResponse输出数据
- */
- @RequestMapping("/return-void-ajax.do")
- public void returnVoidAjax(HttpServletResponse response,String name,String age) throws IOException {
- //调用service得到对象结果
- Student student = new Student();
- student.setName(name);
- student.setName(age);
-
- //把对象转为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(student);
- System.out.println("服务器端对象转为json==" + json);
-
- //输出json,相应ajax
- response.setContentType("application/json;charset=utf-8");
- PrintWriter pw = response.getWriter();
- pw.println(json);
- pw.flush();
- pw.close();
-
- }
- }
2.3.4.1 HttpMessageConverter 消息转换器
HttpMessageConverter 接口作用:
- public interface HttpMessageConverter<T> {
- /**
- * 作用: 检查clazz这个类型的对象,能否转为 mediaType表示的数据格式
- * 如果能转为mediaType表示的类型, 返回true, 返回true调用read()
- */
- boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
-
- /**
- * 作用: 接收请求中的数据,把数据转为 clazz表示的对象
- */
- T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
-
- /**
- * 作用:检查clazz这种数据类型,能否转为mediaType表示的数据格式
- */
- boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
-
- /**
- * 作用: 把t对象,按照contentType说明的格式,把对象转为json或者xml
- */
- void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
- }
MediaType:媒体类型,表示互联网中数据的格式。例如application/json, text/html, image/gif
怎么使用实现类:
- public class doReceiveObject {
-
- @RequestMapping("/receive-object.do")
- public Student doReceiveObject(String name, Integer age) {
- System.out.println("MyController的方法doReceiveObject=");
- Student student = new Student();
- student.setName("lisi");
- student.setAge(20);
- return student;
- }
-
- }
说明
mvc:annotation-driven
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/cache"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
-
- <!-- springmvc配置文件 -->
- <!-- 注解扫描 -->
- <context:component-scan base-package="com.crane.springmvc"></context:component-scan>
-
- <!-- 声明视图解析器: 帮助处理视图
- 作用:简化controller中的写法:
- 之前: modelAndView.setViewName("WEB-INF/view/show.jsp");
- 现在: modelAndView.setViewName("show");
- -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!-- 前缀:指定视图文件的路径-->
- <property name="prefix" value="/WEB-INF/view/"></property>
- <!-- 后缀:指定视图文件的扩展名-->
- <property name="suffix" value=".jsp"></property>
- </bean>
-
- <!-- 声明注解驱动,创建HttpMessageConverter接口的7个实现类对象-->
- <mvc:annotation-driven></mvc:annotation-driven>
- </beans>
2.3.4.2 @ResponseBody
- //输出json,相应ajax
- response.setContentType("application/json;charset=utf-8");
- PrintWriter pw = response.getWriter();
- pw.println(json);
- pw.flush();
- pw.close();
以下两个是等价的:
- /**
- * 控制器返回void,相应ajax请求,使用HttpServletResponse输出数据
- */
- @RequestMapping("/return-void-ajax.do")
- public void returnVoidAjax(HttpServletResponse response,String name,String age) throws IOException {
- //调用service得到对象结果
- Student student = new Student();
- student.setName(name);
- student.setName(age);
-
- //把对象转为json
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(student);
- System.out.println("服务器端对象转为json==" + json);
-
- //输出json,相应ajax
- response.setContentType("application/json;charset=utf-8");
- PrintWriter pw = response.getWriter();
- pw.println(json);
- pw.flush();
- pw.close();
-
- }
- /**
- * 控制器方法返回Student-Json
- * application/json;charset=utf-8
- * 框架的处理模式:
- * 1、框架根据控制器方法的返回值类型,找到HttpMessageConvert接口的实现类,
- * 最后找到的是Mappingjackson2HttpMessageConvert.
- *. 2、使用Mappingjackson2HttpMessageConvert执行write方法,把对象student转为json格
- *。 式数据。
- *。 3、框架使用 @ResponseBody将json数据输出给浏览器
- */
- @RequestMapping("/doStudentJson.do")
- @ResponseBody
- public Student doAjaxJson(HttpServletResponse response,String name,String age) throws IOException {
- //调用service得到对象结果
- Student student = new Student();
- student.setName(name);
- student.setName(age);
- return student;
- }
2.3.4.3 、控制器方法返回返回list---array
2.3.4.3 、控制器方法返回返回String
doStringData方法返回的字符串默认的格式为文本,是ISO-8859-1格式,输出到浏览器会出现乱码。
解决办法是:在@ReqeustMapping中加属性produces=“text/plain;charset=utf-8
2.3.4. 控制器方法返回对象转为json的步骤
访问地址:
当web.xml中DispatcherServlet的url-pattern是 *.do
tomcat安装目录/conf/web.xml
default叫做默认servlet,作用:
他提供静态资源的处理
他处理所有未映射到其他资源的请求处理:即下图中的c
http://localhost:8080/ch05_url_pattern/index.jsp tomcat 成功访问
http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/images/p1.jpg 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/html/test.html 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/some.do 200 MyController
在springmvc的配置文件加入 mvc:default-servlet-handler 标签, springmvc框架会在项目运行时,加入DefaultServletHttpRequestHandler对象,让这个对象处理静态资源的访问。
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/cache"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
-
-
- <!--声明静态资源的第一种处理方式 -->
- <mvc:default-servlet-handler/>
-
- </beans>
注意:default-servlet-handler和@RequestMapping使用存在冲突,导致动态资源不能访问。
解决办法:加上<mvc:annotation-driven />
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/cache"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
-
- <!-- springmvc配置文件 -->
- <!-- 注解扫描 -->
- <context:component-scan base-package="com.crane.springmvc"></context:component-scan>
-
- <!-- 声明视图解析器: 帮助处理视图
- 作用:简化controller中的写法:
- 之前: modelAndView.setViewName("WEB-INF/view/show.jsp");
- 现在: modelAndView.setViewName("show");
- -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <!-- 前缀:指定视图文件的路径-->
- <property name="prefix" value="/WEB-INF/view/"></property>
- <!-- 后缀:指定视图文件的扩展名-->
- <property name="suffix" value=".jsp"></property>
- </bean>
-
- <!-- 声明注解驱动,创建HttpMessageConverter接口的7个实现类对象-->
- <mvc:annotation-driven />
-
- <!--声明静态资源的第一种处理方式 -->
- <mvc:default-servlet-handler />
-
- </beans>
在springmvc配置文件中加入 mvc:resources 标签, 框架会创建ResourceHttpRequestHandler控制器对象, 使用这个对象处理静态资源的访问。不依赖tomcat服务器。 推荐使用的。
-
- <mvc:annotation-driven />
- <!--声明静态资源的第二种处理方式
- mapping: 访问静态资源的uri地址, 可以使用通配符(**)
- ** : 表示任意的目录和目录和资源名称
- location: 静态资源在项目中的位置, 不要使用/WEB-INF目录
- -->
- <mvc:resources mapping="/images/**" location="/images/" />
- <mvc:resources mapping="/html/**" location="/html/" />
- <mvc:resources mapping="/js/**" location="/js/" />
- <!-- 一句话设置静态资源 -->
- <!-- <mvc:resources mapping="/static/**" location="/static/" /> -->
注意:mvc:resources和@RequestMapping使用存在冲突,导致动态资源不能访问。
解决办法:加上<mvc:annotation-driven />
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。