惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
F
Full Disclosure
Cloudbric
Cloudbric
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
N
News and Events Feed by Topic
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
B
Blog
GbyAI
GbyAI
C
Check Point Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
O
OpenAI News
V
V2EX
人人都是产品经理
人人都是产品经理
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Security @ Cisco Blogs
C
Cisco Blogs
Security Latest
Security Latest
S
Security Affairs
V
Visual Studio Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
Last Week in AI
Last Week in AI
AWS News Blog
AWS News Blog
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
博客园_首页
U
Unit 42
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
L
LINUX DO - 热门话题
H
Hacker News: Front Page

博客园 - 两耳不闻窗外事、一心只做程序员

转发 关于Windows安装解压版MySQL出现服务正在启动-服务无法启动的问题 CentOS 安装 jdk1.8 转:MyBatis 日志打印 转:APP开发浅谈-Fiddler抓包详解 C#中用DateTime的ParseExact方法解析日期时间(excel中使用系统默认的日期格式) java程序中的乱码方案 转: 解决Setting property 'source' to 'org.eclipse.jst.jee.server的问题 转:Eclipse中web项目部署至Tomcat步骤 google chrome 浏览器去掉 XHR finished loading.... [转]AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式 下载Tomcat时Tomcat网站上的core和deployer的区别 vmware 修改IP 提示子网掩码错误~ android ImageView 中的ScaleType vs文件属性(生成操作)各选项功能(发布Web项目时使用) 导入 RecyclerView 控件 的过程(Android 6.0) Android RelativeLayout用到的一些重要的属性 Andriod中textview垂直水平居中及LinearLayout内组件的垂直布局 requestWindowFeature(Window.FEATURE_NO_TITLE)无效解决方法 使用VS2013逆向生成UML类图
SpringMVC Controller接收前台ajax的GET或POST请求返回各种参数
两耳不闻窗外事、一心只做程序员 · 2017-02-07 · via 博客园 - 两耳不闻窗外事、一心只做程序员

这几天写新项目遇到这个问题,看这位博主总结得不错,懒得写了,直接转!原文:http://blog.csdn.net/yixiaoping/article/details/45281721原文有些小错误,加上个人比较喜欢markdown写东西,重新编排了下。

闲话少说,刚开始用SpringMVC, 页面要使用jquery的ajax请求Controller。 但总是失败,主要表现为以下两个异常为:

异常一:java.lang.ClassNotFoundException: org.springframework.http.converter.json.MappingJacksonHttpMessageConverter

异常二:SpringMVC @ResponseBody 415错误处理

网上分析原因很多,但找了很久都没解决,基本是以下几类:

  1. springmvc添加配置、注解;
  2. pom.xml添加jackson包引用;
  3. Ajax请求时没有设置Content-Type为application/json
  4. 发送的请求内容不要转成JSON对象,直接发送JSON字符串即可

这些其实都没错!!! 
以下是我分析的解决步骤方法:

(1)springMVC配置文件开启注解

1 <!-- 开启注解-->
2     <mvc:annotation-driven />

(2)添加springMVC需要添加如下配置。 (这个要注意spring版本,3.x和4.x配置不同)

  • spring3.x是org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
  • spring4.x是org.springframework.http.converter.json.MappingJackson2HttpMessageConverter

具体可以查看spring-web的jar确认,哪个存在用哪个! 
spring3.x配置:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonHttpMessageConverter" />
            </list>
        </property>
    </bean>

    <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

spring4.x配置:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonHttpMessageConverter" />
            </list>
        </property>
    </bean>

    <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

(3)pom.xml添加jackson依赖(这个要注意spring版本,3.x和4.x配置不同)

如果是spring 3.x,pom.xml添加如下配置

<dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-lgpl</artifactId>
            <version>1.8.1</version>
         </dependency>


        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-lgpl</artifactId>
            <version>1.8.1</version>
        </dependency></span>

spring4.x, pom.xml添加如下配置

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.5.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.2</version>
        </dependency>

这里要说明一下,spring3.x用的是org.codehaus.jackson的1.x版本,在maven资源库,已经不在维护,统一迁移到com.fasterxml.jackson,版本对应为2.x 
(4)ajax请求要求

dataType 为 json 
contentType 为 ‘application/json;charse=UTF-8’ 
data 转JSON字符串

我的代码如下: 
(注意:这里只是针对POST +JSON字符串形式请求,后面我会详细讲解不同形式请求,的处理方法和案例)

var data = {
        userAccount: lock_username,
        userPasswd:hex_md5(lock_password).toUpperCase()
     }

     $.ajax({
            url : ctx + "/unlock.do",
            type : "POST",
            data : JSON.stringify(data),
                dataType: 'json',
                    contentType:'application/json;charset=UTF-8',    
            success : function(result) {
                console.log(result);
            }
     });

(5) Controller 接收响应JSON

以上配置OK,Controller中使用JSON方式有多种。这里简单介绍几种。

这个关键在于ajax请求是将数据以什么形式传递到后台,这里我总结了三种形式

    1. POST + JSON字符串形式
    2. POST + JSON对象形式
    3. GET + 参数字符串 
      方式一: POST + JSON字符串形式,如下:
    4. //请求数据,登录账号 +密码
           var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : JSON.stringify(data), //转JSON字符串
                  dataType: 'json',
                  contentType:'application/json;charset=UTF-8', //contentType很重要   
                  success : function(result) {
                      console.log(result);
                  }
           });

      方式二: POST + JSON对象形式,如下:

    5.  //请求数据,登录账号 +密码
           var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : data, //直接用JSON对象
                  dataType: 'json',
                  success : function(result) {
                      console.log(result);
                  }
           });

      代码案例:

      5-1: 使用@RequestBody来设置输入 ,@ResponseBody设置输出 (POST + JSON字符串形式)

      JS请求:

       //请求数据,登录账号 +密码
           var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : JSON.stringify(data), //转JSON字符串
                  dataType: 'json',
                  contentType:'application/json;charset=UTF-8', //contentType很重要   
                  success : function(result) {
                      console.log(result);
                  }
           });

      Controller处理:

    6. @RequestMapping(value = "/unlock", method = RequestMethod.POST,consumes = "application/json") 
          @ResponseBody
          public Object unlock(@RequestBody User user) {  
              JSONObject jsonObject = new JSONObject();  
      
              try{
                  Assert.notNull(user.getUserAccount(), "解锁账号为空");
                  Assert.notNull(user.getUserPasswd(), "解锁密码为空");
      
                  User currentLoginUser = (User) MvcUtils.getSessionAttribute(Constants.LOGIN_USER);
                  Assert.notNull(currentLoginUser, "登录用户已过期,请重新登录!");
      
                  Assert.isTrue(StringUtils.equals(user.getUserAccount(),currentLoginUser.getUserAccount()), "解锁账号错误");
                  Assert.isTrue(StringUtils.equalsIgnoreCase(user.getUserPasswd(),currentLoginUser.getUserPasswd()), "解锁密码错误");
      
      jsonObject.put("message", "解锁成功");  
      jsonObject.put("status", "success");
              }catch(Exception ex){
                  jsonObject.put("message", ex.getMessage());  
                      jsonObject.put("status", "error");
              }
             return jsonObject;  
          }  

      5-2: 使用HttpEntity来实现输入绑定,来ResponseEntit输出绑定(POST + JSON字符串形式)

      JS请求:

    7.  //请求数据,登录账号 +密码
           var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : JSON.stringify(data), //转JSON字符串
                  dataType: 'json',
                  contentType:'application/json;charset=UTF-8', //contentType很重要   
                  success : function(result) {
                      console.log(result);
                  }
           });

      Controller处理:

    8. @RequestMapping(value = "/unlock", method = RequestMethod.POST,consumes = "application/json") 
          public ResponseEntity<Object> unlock(HttpEntity<User> user) {  
              JSONObject jsonObject = new JSONObject();  
      
              try{
                  Assert.notNull(user.getBody().getUserAccount(), "解锁账号为空");
                  Assert.notNull(user.getBody().getUserPasswd(), "解锁密码为空");
      
                  User currentLoginUser = (User) MvcUtils.getSessionAttribute(Constants.LOGIN_USER);
                  Assert.notNull(currentLoginUser, "登录用户已过期,请重新登录!");
      
                  Assert.isTrue(StringUtils.equals(user.getBody().getUserAccount(),currentLoginUser.getUserAccount()), "解锁账号错误");
                  Assert.isTrue(StringUtils.equalsIgnoreCase(user.getBody().getUserPasswd(),currentLoginUser.getUserPasswd()), "解锁密码错误");
      
                         jsonObject.put("message", "解锁成功");  
                         jsonObject.put("status", "success");
              }catch(Exception ex){
                  jsonObject.put("message", ex.getMessage());  
                      jsonObject.put("status", "error");
              }
              ResponseEntity<Object> responseResult = new ResponseEntity<Object>(jsonObject,HttpStatus.OK);
                  return responseResult;
          }  

      5-3: 使用request.getParameter获取请求参数,响应JSON(POST + JSON对象形式) 和(GET + 参数字符串),Controller处理一样,区别在于是否加注解method ,

      如果不加适用GET + POST ;

      如果 method= RequestMethod.POST,用于POST 请求;

      如果method=RequestMethod.GET,用于GET请求;

      POST+ JSON对象形式请求:

    9. var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : data,
                  dataType: 'json',
                  success : function(result) {
                      console.log(result);
                  }
           });

      GET + 参数字符串请求:

    10. $.ajax({
                  url : ctx + "/unlock.do",
                  type : "GET",
                  dataType: "text", 
                  data : "userAccount="+lock_username+"&userPasswd=" + hex_md5(lock_password).toUpperCase(),//等价于URL后面拼接参数
                  success : function(result) {
                      console.log(result);
                  }
           });

      Controller处理:

    11. @RequestMapping(value = "/unlock") 
          public void unlock(HttpServletRequest request,HttpServletResponse response)  throws IOException {  
              JSONObject jsonObject = new JSONObject();  
      
              String userAccount = (String)request.getParameter("userAccount");
              String userPasswd = (String)request.getParameter("userPasswd");
              try{
                  Assert.notNull(userAccount, "解锁账号为空");
                  Assert.notNull(userPasswd, "解锁密码为空");
      
                  User currentLoginUser = (User) MvcUtils.getSessionAttribute(Constants.LOGIN_USER);
                  Assert.notNull(currentLoginUser, "登录用户已过期,请重新登录!");
               Assert.isTrue(StringUtils.equals(userAccount,currentLoginUser.getUserAccount()), "解锁账号错误");
                     Assert.isTrue(StringUtils.equalsIgnoreCase(userPasswd,currentLoginUser.getUserPasswd()), "解锁密码错误");
      
                  jsonObject.put("message", "解锁成功");  
                  jsonObject.put("status", "success");
              }catch(Exception ex){
                  jsonObject.put("message", ex.getMessage());  
                  jsonObject.put("status", "error");
              }
      
              response.getWriter().print(jsonObject.toString());  
          }  

      5-4: 使用@ModelAttribute将参数封装对象,响应JSON(POST + JSON对象形式) 和(GET + 参数字符串),Controller处理一样,区别在于是否加注解method 。

      如果不加适用GET + POST ;

      如果 method= RequestMethod.POST,用于POST 请求;

      如果method=RequestMethod.GET,用于GET请求; 
      POST+ JSON对象形式请求:

    12. var data = {
                   userAccount: lock_username,
                   userPasswd:hex_md5(lock_password).toUpperCase()
           }
      
           $.ajax({
                  url : ctx + "/unlock.do",
                  type : "POST",
                  data : data,
                  dataType: 'json',
                  success : function(result) {
                      console.log(result);
                  }
           });

      GET + 参数字符串请求:

    13. $.ajax({
                  url : ctx + "/unlock.do",
                  type : "GET",
                  dataType: "text", 
                  data : "userAccount="+lock_username+"&userPasswd=" + hex_md5(lock_password).toUpperCase(),//等价于URL后面拼接参数
                  success : function(result) {
                      console.log(result);
                  }
           });

      Controller处理:(这个案例只支持POST)

    14. @RequestMapping(value = "/unlock",method = RequestMethod.POST) 
          public void unlock(@ModelAttribute("user") User user,PrintWriter printWriter)  throws IOException {  
              JSONObject jsonObject = new JSONObject();  
      
              try{
                  Assert.notNull(user.getUserAccount(), "解锁账号为空");
                  Assert.notNull(user.getUserPasswd(), "解锁密码为空");
      
                  User currentLoginUser = (User) MvcUtils.getSessionAttribute(Constants.LOGIN_USER);
                  Assert.notNull(currentLoginUser, "登录用户已过期,请重新登录!");          Assert.isTrue(StringUtils.equals(user.getUserAccount(),cur rentLoginUser.getUserAccount()), "解锁账号错误");
                    Assert.isTrue(StringUtils.equalsIgnoreCase(user.getUserPasswd(),currentLoginUser.getUserPasswd()), "解锁密码错误");
      
                  jsonObject.put("message", "解锁成功");  
                  jsonObject.put("status", "success");
              }catch(Exception ex){
                  jsonObject.put("message", ex.getMessage());  
                  jsonObject.put("status", "error");
              }
              printWriter.print(jsonObject.toString());
          }