【问题标题】:ExtJS 4 Spring 3 file upload. Server sends bad response content typeExtJS 4 Spring 3 文件上传。服务器发送错误的响应内容类型
【发布时间】:2011-08-11 09:20:16
【问题描述】:

我正在使用 ExtJS 4 前端和 Spring 3 作为后端创建文件上传。文件上传有效,但服务器的响应内容类型错误。当我使用 Jackson 序列化的Map<String, Object> 发送{success:true} 时,ExtJS 返回错误

Uncaught Ext.Error: You're trying to decode an invalid JSON String: <pre style="word-wrap: break-word; white-space: pre-wrap;">{"success":true}</pre>

为什么我的回复被&lt;pre&gt; 标签包裹?我已经搜索了 found out,例如我应该将响应类型更改为 text/html。但是changing content type in servlet response 没有帮助

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody Map<String, Object> upload(
    FileUpload uploadItem, BindingResult result, HttpServletResponse response) {

    response.setContentType("text/html");

    // File processing   

    Map<String, Object> jsonResult = new HashMap<String, Object>();
    jsonResult.put("success", Boolean.TRUE);
    return jsonResult;
}

当我将upload 方法的返回值更改为String 时,一切正常,但我想返回Map 并让Jackson 对其进行序列化

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody String upload(
    FileUpload uploadItem, BindingResult result, HttpServletResponse response) {

    // File processing   

    return "{success:true}";
}

我的 Spring 配置

<bean 
    id="stringHttpMessageConverter" 
    class="org.springframework.http.converter.StringHttpMessageConverter">
</bean>
<bean 
    id="jacksonMessageConverter" 
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>  
<bean    
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter"/>
            <ref bean="stringHttpMessageConverter" />
        </list>
    </property>
</bean>

如何告诉Spring返回正确的内容类型?当其他方法的响应被正确解释时,为什么这个方法的响应不正确?

【问题讨论】:

  • 你解决了吗?你会分享你的解决方案吗?ty
  • @astrocybernaute 看到我的回答。我希望它会有所帮助

标签: json spring extjs upload response


【解决方案1】:

您需要将响应的内容类型设置为“text/html”。 如果content-type是“application/json”就会有这个问题。很奇怪。

【讨论】:

    【解决方案2】:

    如果你只需要返回成功的值,你可以返回布尔值:

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody boolean upload(
        FileUpload uploadItem, BindingResult result, HttpServletResponse response) {
    
        return true; //or false
    }
    

    【讨论】:

    • 我需要其他返回类型的解决方案 (Map)
    【解决方案3】:

    嗯,不是最好的解决方案,但它解决了问题。我创建了类,其中包含Map 以及将参数添加到Map 的方法。还有实现方法toString()

    public class ExtJSJsonResponse {
    
        /** Parameters to serialize to JSON */
        private Map<String, Object> params = new HashMap<String, Object>();
    
        /**
         * Add arbitrary parameter for JSON serialization. 
         * Parameter will be serialized as {"key":"value"};
         * @param key name of parameter
         * @param value content of parameter
         */
        @JsonIgnore
        public void addParam(String key, Object value) {
            params.put(key, value);
        }
    
        /**
         * Gets all parameters. Also is annotated with <code>@JsonValue</code>.
         * @return all params with keys as map
         */
        @JsonValue
        public Map<String, Object> getParams() {
            return params;
        }
    
        /**
         * Returns specified parameter by <code>key</code> as string "key":"value"
         * @param key parameter key 
         * @return  "key":"value" string or empty string when there is no parameter 
         *          with specified key
         */
        private String paramToString(String key) {
            return params.containsKey(key) 
                ? "\"" + key + "\":\"" + params.get(key) + "\""
                : "";
        }
    
        /**
         * Manually transforms map parameters to JSON string. Used when ExtJS fails 
         * to decode Jackson response. i.e. when uploading file.
         * @return 
         */
        @Override
        @JsonIgnore
        public String toString() {
            StringBuilder sb = new StringBuilder("{");
            String delimiter = "";
    
            for (String key : params.keySet()) {
                sb.append(delimiter);
                sb.append(paramToString(key));
                delimiter = ",";
            }
    
            sb.append("}");
            return sb.toString();
        }
    }
    

    所以当Uncaught Ext.Error: You're trying to decode an invalid JSON String 出现时,您只需这样做

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody String upload(
        FileUpload uploadItem, BindingResult result, HttpServletResponse response) {
        ExtJSJsonResponse response = new ExtJSJsonResponse();
    
        // File processing
        response.addParam("success", true);
        response.addParam("message", "All OK");   
    
        return response.toString();
    }
    

    在其他没有序列化问题的方法中,您可以简单地调用return response;,它将自动序列化。

    方法toString() 仅适用于简单的类,例如String。对于更复杂的类,您必须更改它。

    【讨论】:

      【解决方案4】:

      我认为你可以使用 Spring 的 @RequestMapping 注解的“produces”属性:

      @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = MediaType.TEXT_HTML_VALUE)
      public @ResponseBody Map<String, Object> upload(
          FileUpload uploadItem, BindingResult result, HttpServletResponse response) {
      
          // File processing   
      
          Map<String, Object> jsonResult = new HashMap<String, Object>();
          jsonResult.put("success", Boolean.TRUE);
          return jsonResult;
      }
      

      在配置文件中,你应该使这个 Content-Type 可用:

      <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
          <property name="supportedMediaTypes">
              <array>
                  <value>text/html</value>
                  <value>application/json</value>
              </array>
          </property>
      </bean>  
      

      这在 Spring 3.1.1.RELEASE 中可用,可能在旧版本中不起作用。

      【讨论】:

      • " 此请求标识的资源只能生成具有根据请求“接受”标头()不可接受的特征的响应。指定“produces=MediaType.TEXT_HTML_VALUE”时返回此错误
      猜你喜欢
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 2021-03-28
      • 2022-01-22
      相关资源
      最近更新 更多