Spring MVC 以.html为后缀名访问获取数据,报406 Not Acceptable错误。

如题,最近以spring mvc作为后台框架,前端异步获取数据时(.html为后缀名的访问方式),报406 Not Acceptable错误。当初都不知道啥原因,前后台都没报错就是返回不了数据,于是查了下http 406响应码:406 (SC_NOT_ACCEPTABLE)表示请求资源的MIME类型与客户端中Accept头信息中指定的类型不一致。下面请看出错的操作流程及代码:

1、先配置spring mvc 核心servlet (DispatcherServlet) 至web.xml中,其中配置可以以.html和.do为后缀名的请求。(注意:只显示重要代码,下面也是一样)

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

2、controller部分代码如下:

    @RequestMapping(value="chat/startClient")
    @ResponseBody
    public AjaxResult startClient(UserEntity user,HttpServletRequest request) {
        AjaxResult result = new AjaxResult(1);
        if (user.getUserId() == null){
            user.setUserId(System.currentTimeMillis());
            SessionUtil.setAttr(request, SessionUtil.SESSION_USER, user);
        } else {
            UserEntity sessionUser = SessionUtil.getUser(request);
            if (sessionUser.getUserId().equals(user.getUserId())) {
               user = sessionUser;
            }
        }
        if (Client.startClient(user)) {
            result.setData(user);
        }
        return result;
    }

3、jsp 异步请求代码如下:

  $.ajax({
    url:‘${pageContext.request.contextPath}/chat/startClient.html‘,
       dataType: ‘json‘,
       data:{userId:$("input[name=userId]").val(),userName:$("#userName").val()},
    success: function(result){
         var state = result.error;
          if(state == 1){
         $(‘.modal-header .close‘).click();
        $("input[name=userName]").val($("#userName").val());
      }
    }
  });

配置以上代码启动项目访问上面jsp中的异步方法时,通过浏览器的开发者工具(google)查看请求结果如下,通过响应头来看Content-type确实不一样,返回的是text/html,而请求的是application/json,所以浏览器无法解析或者接受这样的类型,就报错406错误。

针对上面情况在网上折腾了一会,终于找到了破解之法,该问题的主要原因:Spring MVC有点不一样,如果你没有配置什么样的请求方式对应什么样的响应方式的话,它会根据url的后缀名对应不同响应头的格式,如下:

public class MediaType extends MimeType
  implements Serializable
{
  private static final long serialVersionUID = 2069937152339670231L;
  public static final MediaType ALL = valueOf("*/*");
  public static final String ALL_VALUE = "*/*";
  public static final MediaType APPLICATION_ATOM_XML = valueOf("application/atom+xml");
  public static final String APPLICATION_ATOM_XML_VALUE = "application/atom+xml";
  public static final MediaType APPLICATION_FORM_URLENCODED = valueOf("application/x-www-form-urlencoded");
  public static final String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded";
  public static final MediaType APPLICATION_JSON = valueOf("application/json");
  public static final String APPLICATION_JSON_VALUE = "application/json";
  public static final MediaType APPLICATION_OCTET_STREAM = valueOf("application/octet-stream");
  public static final String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream";
  public static final MediaType APPLICATION_XHTML_XML = valueOf("application/xhtml+xml");
  public static final String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xml";
  public static final MediaType APPLICATION_XML = valueOf("application/xml");
  public static final String APPLICATION_XML_VALUE = "application/xml";
  public static final MediaType IMAGE_GIF = valueOf("image/gif");
  public static final String IMAGE_GIF_VALUE = "image/gif";
  public static final MediaType IMAGE_JPEG = valueOf("image/jpeg");
  public static final String IMAGE_JPEG_VALUE = "image/jpeg";
  public static final MediaType IMAGE_PNG = valueOf("image/png");
  public static final String IMAGE_PNG_VALUE = "image/png";
  public static final MediaType MULTIPART_FORM_DATA = valueOf("multipart/form-data");
  public static final String MULTIPART_FORM_DATA_VALUE = "multipart/form-data";
  public static final MediaType TEXT_HTML = valueOf("text/html");
  public static final String TEXT_HTML_VALUE = "text/html";
  public static final MediaType TEXT_PLAIN = valueOf("text/plain");
  public static final String TEXT_PLAIN_VALUE = "text/plain";
  public static final MediaType TEXT_XML = valueOf("text/xml");
  public static final String TEXT_XML_VALUE = "text/xml";
  private static final String PARAM_QUALITY_FACTOR = "q";
}

解决方法:所以我们要针对此情况进行配置,更改html对应返回的类型。(注意:1、先声明下我使用的spring 版本:4.1.9,2、如果想要使用@ResponseBody返回json格式,就需要加载这三个包:jackson-core、jackson-databind和jackson-annotations,请自行去mvn repository中获取) 一般我们是配置在mvc配置文件中需要配置<mvc:annotation-driven />, 所以我们只要修改下这里就行,修改配置代码如下:

    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
    <!-- 以.html为后缀名访问,默认返回数据类型是 text/html, 所以要修改返回的数据类型 -->
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <map>
                <entry key="html" value="application/json;charset=UTF-8"/>
            </map>
        </property>
    </bean>

ContentNegotiationManagerFactoryBean 是内容协商管理工厂bean对象,主要用来配置多视图请求格式。

其中有人问我说,为什么要用.html作为后缀名访问,如果不用它的话也不会有这样的错误出现,多省事。 其实我我觉的用.html作为后缀名访问的话,使得url形成了一种伪路径,相对来说增强了安全性。

时间: 2024-09-29 16:34:14

Spring MVC 以.html为后缀名访问获取数据,报406 Not Acceptable错误。的相关文章

Spring Mvc Web 配置拦截规则与访问静态资源 (三)

拦截规则配置 1. *.do <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name

spring Mvc Web 编码相关 [model 到 视图传递数据] (九)

在某种编码环境,由bean注解的参数可能会发生乱码问题. 即可页面web.xml或其他地方都设备UTF-8, 但还是会有这样的问题. 首先不要使用model传到视图的数据. 第二,不要request.getParamer或request.getAttribute方式,这其他就有解码内置. 第三,首先对传进来的url,其中有汉字的进行escape加码,再传到目标端. 第四,经过escape的参数,使用request.getParameter或attribute获取值为 null spring Mv

Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.lang.NullPointerException) 按上述步骤解决完自己的工具类后,你会发现项目运行后仍然报空指针此时你需要在applicationContext.xml 配置文件中添加一行配置文件 如图: 对自己工具类所在的包进行注解扫描,使Spring能够识别自己上面所配置的注解 原文地址:htt

Spring MVC:解决静态资源无法访问的问题

解决静态资源不能访问的问题,解决方式有三种: 使用defaultServlet打开tomcat中conf/web.xml,在这个文件中有一个叫做DefaultServlet的配置,当系统找不到处理某次url请求该交由谁处理的时候,就会交给这个servlet处理.我们可以通过使用这个DefaultServlet来处理静态资源,在你的系统中的web.xml文件中添加下面配置,要添加在DispatcherServlet的前面,这样系统就会将带有下面后缀名的请求交给defaultservlet来处理:

Spring MVC Restful构建中静态资源访问问题

在构建Spring MVC Restful风格的应用时,由于在web.xml中: <span style="font-family:Microsoft YaHei;font-size:18px;"><servlet> <servlet-name>story</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</se

spring mvc 配置对静态资源的访问

在spring mvc的配置文件中做如下配置: 1. <?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:tx="http://www.s

layui图片上传之后后台如何修改图片的后缀名以及返回数据给前台

const pathLib = require('path');//引入node.js下的一个path模块的方法,主要处理文件的名字等工作,具体可看文档 const fs = require(''fs); var app = new express(); //前台图片上传访问路径 app.post('/upload',(req,res)=>{ if(Boolean(typeof req.files[0])){//判断访问该后台时是否有图片上传 var ext = pathLib.parse(re

去除路径中的后缀名和获取路径目录

首先,记录一个网址,感觉很有用,大部分的文件路径相关函数,里面都有源代码. https://msdn.microsoft.com/en-us/library/windows/desktop/bb773746(v=vs.85).aspx 1.完整路径,去除后缀名   PathRemoveExtensionA [cpp] view plain copy #include <iostream>//cout函数所需 #include "atlstr.h"  //PathRemove

Spring MVC通过Pageable对象和PageableDefault注解获取分页信息(MongoDB通过Pageable来操作分页)

说明:Pageable同时也能用于操作MongoDB的分页. PageableSpring Data库中定义的一个接口,该接口是所有分页相关信息的一个抽象,通过该接口,我们可以得到和分页相关所有信息(例如pageNumber.pageSize等). Pageable定义了很多方法,但其核心的信息只有两个:一是分页的信息(page.size),二是排序的信息. 在Spring MVC的请求中只需要在方法的参数中直接定义一个Pageable类型的参数,当Spring发现这个参数时,Spring会自动