abi 问题 return display project rep 求和 sum
前言
主要介绍自己在学习 spring mvc 过程中踩到的一些坑,涉及到当时遇到这个错误是如何思考的,对思路进行总结,下次遇到类似的错误能够提供一些思路甚至快速解决。
环境准备
jdk8,spring4.3.3.RELEASE,spring mvc 与 spring 版本一致,maven3.2.5,tomcat7
目标:
1. 测试 spring mvc 的 json 参数绑定功能
2. 测试 spring mvc 的返回 json 功能
项目目录 (已经推送到 github:https://github.com/ComingOnuguys/frankwin):
测试 1 相关代码:index.jsp
- 1<%@ page language="java" contentType="text/html; charset=utf-8" 2pageEncoding="utf-8"%> 3 4 5 6 7 8 9src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js">10111213id:14menuName:15
- 1617
- 1819window.onload = function() {
- 20$("#abc").click(function() {
- 21var menu = {
- 22"id" : $("#id").val(),
- 23"menuName" : $("#menuName").val()
- 24 };
- 25var jsonStr = JSON.stringify(menu);
- 26 $.ajax({
- 27type : "POST",
- 28async :false,
- 29url : "http://localhost:8080/ssm/getList",
- 30dataType : "json",
- 31contentType : "application/json;charset=UTF-8",
- 32 data : jsonStr,
- 33 success : function(data) {
- 34alert("123");
- 35 }
- 36 });
- 37 });
- 38 }
- 394041
getList.jsp(为了返回的时候不报 404 的错)
- 1<%@ page language="java" contentType="text/html; charset=utf-8" 2pageEncoding="utf-8"%> 3 4 5 6 7 8 91011
- 12
- 陈公告
- 13
- 1415
TestSpringMvcController.java
- 1 package com.dg.action;
- 2
- 3 import org.springframework.stereotype.Controller;
- 4 import org.springframework.web.bind.annotation.RequestBody;
- 5 import org.springframework.web.bind.annotation.RequestMapping;
- 6
- 7 import com.dg.bean.Menu;
- 8
- 9 @Controller
- 10 public class TestSpringMvcController {
- 11
- 12@RequestMapping("getList")
- 13 public void getList(@RequestBody Menu menu){
- 14System.out.println("menu:" + menu);
- 15 }
- 16}
Menu.java
- 1 package com.dg.bean;
- 2 3 import java.io.Serializable;
- 4 5 public class Menu implements Serializable {
- 6 7 private static final long serialVersionUID = 410202860691610816L;
- 8 private String id;
- 9 private String menuCode;
- 10 private String menuName;
- 11 private String menuUrl;
- 12 private String parentMenuId;
- 13 14 public String getId() {
- 15
- return id;
- 16
- }
- 17 18 public void setId(String id) {
- 19 this.id = id;
- 20
- }
- 21 22 public String getMenuCode() {
- 23
- return menuCode;
- 24
- }
- 25 26 public void setMenuCode(String menuCode) {
- 27 this.menuCode = menuCode;
- 28
- }
- 29 30 public String getMenuName() {
- 31
- return menuName;
- 32
- }
- 33 34 public void setMenuName(String menuName) {
- 35 this.menuName = menuName;
- 36
- }
- 37 38 public String getMenuUrl() {
- 39
- return menuUrl;
- 40
- }
- 41 42 public void setMenuUrl(String menuUrl) {
- 43 this.menuUrl = menuUrl;
- 44
- }
- 45 46 public String getParentMenuId() {
- 47
- return parentMenuId;
- 48
- }
- 49 50 public void setParentMenuId(String parentMenuId) {
- 51 this.parentMenuId = parentMenuId;
- 52
- }
- 53 54@Override 55 public String toString() {
- 56
- return "Menu [id=" + id + ", menuCode=" + menuCode + ", menuName=" + menuName + ", menuUrl=" + menuUrl 57 + ", parentMenuId=" + parentMenuId + "]";
- 58
- }
- 59
- }
spring-config.xml(进行了最大程度精简)
- 1 <?xml version="1.0" encoding="UTF-8"?>
- 2 <beans xmlns="http://www.springframework.org/schema/beans"
- 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
- 5
- 6
- 7 </beans>
spring-mvc.xml
- 1 2 3xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4xmlns:context="http://www.springframework.org/schema/context" 5xmlns:mvc="http://www.springframework.org/schema/mvc" 6xsi:schemaLocation="http://www.springframework.org/schema/beans 7http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- 8http://www.springframework.org/schema/context
- 9http://www.springframework.org/schema/context/spring-context-4.0.xsd
- 10http://www.springframework.org/schema/mvc
- 11http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
- 12">13[email protected]-->14package="com.dg.action" />15
- 161718
- 1920<bean
- 21 class="org.springframework.web.servlet.view.InternalResourceViewResolver">22
- 23
- 2425
- 26
- 27
web.xml
- 1 <?xml version="1.0" encoding="UTF-8"?>
- 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 3 xmlns="http://java.sun.com/xml/ns/javaee"
- 4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- 5 version="3.0">
- 6 <display-name>ssm</display-name>
- 7 <!-- Spring和mybatis的配置文件 -->
- 8 <context-param>
- 9 <param-name>contextConfigLocation</param-name>
- 10 <param-value>classpath:spring-config.xml</param-value>
- 11 </context-param>
- 12 <!-- 编码过滤器 -->
- 13 <filter>
- 14 <filter-name>encodingFilter</filter-name>
- 15 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
- 16 <async-supported>true</async-supported>
- 17 <init-param>
- 18 <param-name>encoding</param-name>
- 19 <param-value>UTF-8</param-value>
- 20 </init-param>
- 21 </filter>
- 22 <filter-mapping>
- 23 <filter-name>encodingFilter</filter-name>
- 24 <url-pattern>/*</url-pattern>
- 25 </filter-mapping>
- 26 <!-- Spring监听器 -->
- 27 <listener>
- 28 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- 29 </listener>
- 30 <!-- 防止Spring内存溢出监听器 -->
- 31 <listener>
- 32 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
- 33 </listener>
- 34
- 35 <!-- Spring MVC servlet -->
- 36 <servlet>
- 37 <servlet-name>SpringMVC</servlet-name>
- 38 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- 39 <init-param>
- 40 <param-name>contextConfigLocation</param-name>
- 41 <param-value>classpath:spring-mvc.xml</param-value>
- 42 </init-param>
- 43 <load-on-startup>1</load-on-startup>
- 44 <async-supported>true</async-supported>
- 45 </servlet>
- 46 <servlet-mapping>
- 47 <servlet-name>SpringMVC</servlet-name>
- 48 <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
- 49 <url-pattern>/</url-pattern>
- 50 </servlet-mapping>
- 51 <!-- 设置静态资源映射 -->
- 52 <servlet-mapping>
- 53 <servlet-name>default</servlet-name>
- 54 <url-pattern>*.jpg</url-pattern>
- 55 </servlet-mapping>
- 56 <servlet-mapping>
- 57 <servlet-name>default</servlet-name>
- 58 <url-pattern>*.gif</url-pattern>
- 59 </servlet-mapping>
- 60
- 61 <servlet-mapping>
- 62 <servlet-name>default</servlet-name>
- 63 <url-pattern>*.png</url-pattern>
- 64 </servlet-mapping>
- 65
- 66 <servlet-mapping>
- 67 <servlet-name>default</servlet-name>
- 68 <url-pattern>*.js</url-pattern>
- 69 </servlet-mapping>
- 70 <servlet-mapping>
- 71 <servlet-name>default</servlet-name>
- 72 <url-pattern>*.css</url-pattern>
- 73 </servlet-mapping>
- 74 <welcome-file-list>
- 75 <welcome-file>/index.jsp</welcome-file>
- 76 </welcome-file-list>
- 77
- 78 </web-app>
pom.xml
- 1 <?xml version="1.0" encoding="UTF-8"?>
- 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- 4
- 5 <modelVersion>4.0.0</modelVersion>
- 6 <packaging>war</packaging>
- 7
- 8 <name>ssm</name>
- 9 <groupId>dg</groupId>
- 10 <artifactId>ssm</artifactId>
- 11 <version>0.0.1-SNAPSHOT</version>
- 12
- 13 <properties>
- 14 <!-- spring版本号 -->
- 15 <spring.version>4.3.3.RELEASE</spring.version>
- 16 <!-- log4j日志文件管理包版本 -->
- 17 <slf4j.version>1.7.7</slf4j.version>
- 18 <log4j.version>1.2.17</log4j.version>
- 19 </properties>
- 20
- 21 <dependencies>
- 22 <!-- spring核心包 -->
- 23 <dependency>
- 24 <groupId>org.springframework</groupId>
- 25 <artifactId>spring-core</artifactId>
- 26 <version>${spring.version}</version>
- 27 </dependency>
- 28 <dependency>
- 29 <groupId>org.springframework</groupId>
- 30 <artifactId>spring-web</artifactId>
- 31 <version>${spring.version}</version>
- 32 </dependency>
- 33 <dependency>
- 34 <groupId>org.springframework</groupId>
- 35 <artifactId>spring-webmvc</artifactId>
- 36 <version>${spring.version}</version>
- 37 </dependency>
- 38 <!-- 日志文件管理包 -->
- 39 <!-- log start -->
- 40 <dependency>
- 41 <groupId>log4j</groupId>
- 42 <artifactId>log4j</artifactId>
- 43 <version>${log4j.version}</version>
- 44 </dependency>
- 45 <dependency>
- 46 <groupId>org.codehaus.jackson</groupId>
- 47 <artifactId>jackson-mapper-asl</artifactId>
- 48 <version>1.9.13</version>
- 49 </dependency>
- 50
- 51 </dependencies>
- 52 </project>
坑一:spring mvc 的 json 包对于测试 1,采用以上代码一直返回 httpcode415 (Unsupported Media Type)。如下图:
后台报错的日志为:
- 1[org.springframework.web.servlet.DispatcherServlet] - DispatcherServlet with name 'SpringMVC' processing POST requestfor[/ssm/getList]
- 2[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] - Looking up handler methodforpath /getList
- 3[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] - Returning handler method [public void com.dg.action.TestSpringMvcController.getList(com.dg.bean.Menu)]
- 4[org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'testSpringMvcController' 5[org.springframework.web.cors.DefaultCorsProcessor] - Skip CORS processing: request is from same origin
- 6[org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod] - Error resolving argument [0] [type=com.dg.bean.Menu]
- 7 HandlerMethod details:
- 8 Controller [com.dg.action.TestSpringMvcController]
- 9Method [public void com.dg.action.TestSpringMvcController.getList(com.dg.bean.Menu)]
- 10
- 11org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
- 12at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:235)
- 13at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:149)
- 14at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:127)
- 15at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
- 16at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
- 17at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
- 18at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
- 19at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
- 20at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
- 21at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
- 22at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
- 23at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
- 24at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
- 25at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
- 26at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
- 27at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
- 28at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
- 29at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
- 30at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
- 31at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
- 32at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
- 33at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
- 34at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
- 35at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
- 36at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
- 37at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
- 38at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
- 39at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
- 40at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
- 41at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
- 42at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
- 43at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
- 44at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
- 45at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
- 46at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
- 47at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
- 48at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
- 49at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
- 50at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
- 51at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
- 52at java.lang.Thread.run(Thread.java:745)
- 53[org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver] - Resolving exception from handler [public voidcom.dg.action.TestSpringMvcController.getList(com.dg.bean.Menu)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
- 54[org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] - Resolving exception from handler [public voidcom.dg.action.TestSpringMvcController.getList(com.dg.bean.Menu)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
- 55[org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] - Resolving exception from handler [public voidcom.dg.action.TestSpringMvcController.getList(com.dg.bean.Menu)]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
- 56[org.springframework.web.servlet.DispatcherServlet] - Null ModelAndView returned to DispatcherServlet with name 'SpringMVC': assuming HandlerAdapter completed request handling
- 57[org.springframework.web.servlet.DispatcherServlet] - Successfully completed request
- 58
看到这个报错提示的第一反应是把前台请求 index.jsp 的 contentType 这一行注释掉(注:不写默认值是 application/x-www-form-urlencoded;charset=UTF-8)://contentType : "application/json;charset=UTF-8", 报错变成了:Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported 都不支持,[email protected]ody 能不能参数绑定成功,[email protected],前台请求注释 contentType 这一行注释掉,发送的参数由 jsonStr 这个变量改为 menu,发现可以正常注入,根据之前学到的知识,String 类型和 Json 的参数绑定是分别由 StringHttpMessageConverter 和 MappingJackson2HttpMessageConverter 进行处理,于是把断点分别打在两个类的构造方法上,断点情况如图:
启动 tomcat,发现只进到了 StringHttpMessageConverter 这个类的构造函数里面。报错的原因找到了(没有加载 MappingJackson2HttpMessageConverter),但是为什么没有加载,还不知道原因。重新启动 tomcat,顺着 StringHttpMessageConverter 执行下来,发现有这么一段,
看到 MappingJackson2HttpMessageConverter 非常眼熟,但是很遗憾,这里的 jackson2present 变量值是 false,
看到这里,接着就是去找该变量是 false 的原因了。Ctrl+Shift+K 找到声明这个变量的地方,
选中 com.fasterxml.jackson.databind.ObjectMapper,Ctrl+shift+T,没有找到这个类。嗯,问题就处在这了。意思到有可能有什么包没有加进来。查阅资料得知 spring mvc 从 3.2 版本开始依赖的 json 包由原先的 jackson-mapper-asl.jar、jackson-core-asl-1.9.13.jar 变更为了 jackson-core.jar、jackson-dataformat-xml.jar
于是到 mavenrepository 找到 springmvc4.3.3.RELEASE 依赖的包的列表,上面的结论得到验证。
接着修改 maven 依赖 json 的包,再使用上面的那些代码,终于大功告成~
总结:
1、ajax 请求如果不写 contentType,则默认是 application/x-www-form-urlencoded;charset=UTF-8
[email protected] 体类上,要实现这个,请求的 contentType 要设置成 contentType : "application/json;charset=UTF-8"
3、更明确 spring mvc 的这些默认的处理类在 tomcat 容器启动时就进行初始化。
4、当怀疑是包依赖产生的问题时,可以到 mavenrepository 找到该框架依赖的 jar 包。
包依赖的问题解决后,测试 2 也成功实现目标。
(完)
spring mvc 踩坑记
来源: http://www.bubuko.com/infodetail-2049684.html