【问题标题】:HttpServletRequest can not get xhr request parameterHttpServletRequest 无法获取 xhr 请求参数
【发布时间】:2017-03-21 20:01:54
【问题描述】:

我正在使用 Spring 和 javascript。使用 XhrHttpRequest 对象调用 @Controller。

我可以使用 Chrome Inspector 查看我的参数(JSON 字符串),但是当我调用 request.getParamter("id") 时返回 null。

Calling part with js
function ajax(url, data, callback, method){
    //data is {"id":"system", "password" : "1234"}
    var httpRequest;
    var afterAction = function(){
        if(!httpRequest) {
            console.error('can not find httpRequest variable');
            return;
        }

        if (httpRequest.readyState === XMLHttpRequest.DONE) {
            if (httpRequest.status === 200) {
                var responseData = httpRequest.responseText;
                //alert(JSON.stringify(responseData));
                console.log('Result of API call >>>', responseData);
                if(typeof callback == 'function') {
                    callback(JSON.parse(responseData));
                }
            } else {
                alert('There was a problem with the request.');
            }
        }
    }

    //=========== LOGIC ============
    if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
        httpRequest = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE 6 and older
        httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
    }

    if(!method) method = 'POST';
    data = (!!data) ? JSON.stringify(data) : '';

    httpRequest.onreadystatechange = afterAction;
    httpRequest.open(method.toUpperCase(), url, true);
    httpRequest.setRequestHeader("Content-type", "application/json; charset=utf-8");
    //httpRequest.setRequestHeader("Content-length", data.length);
    //httpRequest.setRequestHeader("Connection", "close");
    httpRequest.send(data);
}

使用 Spring @Controller 接收零件

@Controller
@RequestMapping(value={"member"}, produces={"application/json"})
@ResponseStatus(value = HttpStatus.OK)
public class MemberController {

    /**
     * @param request
     * @param resp
     * @return
     * @throws Exception
     */
    @RequestMapping(value={"/login"})
    public @ResponseBody String login(HttpServletRequest request, HttpServletResponse resp) throws Exception {
        System.out.println("Login request");
        String id = String.valueOf(request.getParameter("id"));                 //returns null
        String password = String.valueOf(request.getParameter("password"));     //returns null

        Map<String, String> result = new HashMap<String, String>();
        result.put("result", "S");
        result.put("message", "login success");
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(result);
    }
}

我不知道为什么参数变为空。谢谢。

【问题讨论】:

  • JSON 正文不是请求参数。所以很明显getParameter 将返回null。您将需要解析正文而不是参数。
  • @M.Deinum 我的一位朋友建议使用Converter,我将对其进行测试并添加到这篇文章中。感谢分享信息

标签: javascript spring model-view-controller xmlhttprequest httprequest


【解决方案1】:

这是杰克逊图书馆的另一种方式。我喜欢 @javaguy 的方式,但使用 Jackson 库可能更灵活,所以添加这篇文章。

准备工作

  • WebMvcConfigurerAdapter 实现类或与之等效的东西
  • SpringFramework 环境。在我的例子中,Eclipse Dynamic Web Project 与 Maven 和 spring-webmvc 在 pom.xml 中。

我做了什么...

  • 实现WebMvcConfigurerAdapter
  • 覆盖方法configureMessageConverters
  • 将Controller参数从HttpServeletRequest request, HttpServletResponse resp更改为@RequestBody Map&lt;?, ?&gt;。(您可以更改通用值。进一步处理无关紧要)

下面是代码。

ServerConfig.java(我阻止其他选项以关注当前问题)

@Configuration
@EnableWebMvc
@ComponentScan(basePackages={ ... }
, excludeFilters=@ComponentScan.Filter(Configuration.class))
//Filter 걸 때 Configuration.class 를 수동으로 등록해줘야 되는데 나은 방법 찾아보기 
public class ServerConfig extends WebMvcConfigurerAdapter {

    ...

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter());
        super.configureMessageConverters(converters);
    }

};

和控制器(更改参数类型)

@Controller
@RequestMapping(value={"member"}, produces={"application/json"})
@ResponseStatus(value = HttpStatus.OK)
public class MemberApiController {

    ...

    @RequestMapping(value={"/login"})
    public @ResponseBody String login(@RequestBody Map<?, ?> jsonBody) throws JsonProcessingException {
        System.out.println("Login request" + jsonBody.toString());
        Map<String, String> result = new HashMap<String, String>();
        String rs = "S";
        String message = "SUCCESS";

        System.out.println("ID >>> ", String.valueOf(jsonBody.get("id")));
        System.out.println("PW >>> ", String.valueOf(jsonBody.get("password")));

        result.put("result", rs);
        result.put("result_msg", message);
        mapper = new ObjectMapper();
        return mapper.writeValueAsString(result);
    }
};

但是,据我所知@RequestBody没有HttpSession,如果你尝试将数据存储到HttpSession,你需要另一个参数HttpServletRequest。

我希望这可以帮助与我有同样问题的其他人:D

【讨论】:

  • 无论如何,从HttpServletRequest本身获取JSON值似乎是不可能的。
【解决方案2】:

您需要按照以下步骤在您的控制器中接受Json:

(1) 定义 UserLogin bean 来保存 Json

public class UserLogin  {
    private String id;
    private String password;

    //Add getters and setters
}

(2) 更改您的控制器以接受 Json 并接收 UserLogin bean

@Controller
@RequestMapping(value={"member"}, produces={"application/json"})
@ResponseStatus(value = HttpStatus.OK)
public class MemberController {

    @RequestMapping(value={"/login"}, method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody String login(UserLogin userLogin) throws Exception {
        System.out.println("Login request");
        String id = userLogin.getId();            
        String password = userLogin.getPassword();

        Map<String, String> result = new HashMap<String, String>();
        result.put("result", "S");
        result.put("message", "login success");
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(result);
    }
}

【讨论】:

  • 谢谢。它看起来工作。但是,有没有其他方法可以不产生额外的豆子?因为我不确定用户应该拥有什么数据。(此时可以随时更改,数据库可以接受 - MongoDB)。此外,我想处理可以与其他控制器共享的通用方式。
  • 登录只是一个案例。我将接收 JSON 格式的 API 参数。例如,对于列表{"page" : "1", "pageCount" : "10", "search" : "aaa"}。按照你的建议,我必须为它制作另一个分页 bean,对吧?不过,谢谢,无论如何,您的建议也是很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2018-08-06
  • 2017-05-20
  • 2011-12-22
  • 2017-03-11
  • 1970-01-01
  • 2011-12-27
  • 2020-11-04
  • 2012-01-18
相关资源
最近更新 更多