@ResourceMapping that accepts JSON from Ajax request

你说的曾经没有我的故事 提交于 2019-12-12 08:19:30

问题


I'm searching how I can interprete a JSON parameter in my @ResourceMapping in Spring Portlet MVC. When I add @RequestBody, I got the message: @RequestBody is not supported... Really stuck on this one.

I have this:

View side:

<portlet:resourceURL var="getTest" id="ajaxTest" ></portlet:resourceURL>

    <p>
        <button onClick="executeAjaxTest();">Klik mij!</button>
        <button onClick="$('#ajaxResponse').html('');">Klik mij!</button>
    </p>
    <p>
        <h3>Hieronder het antwoord:</h3>
        <h4 id="ajaxResponse"></h4>
    </p>

    <script>
        function executeAjaxTest() {

            var jsonObj = {
                    user: "Korneel",
                    password: "testpassword",
                    type: {
                        testParam: "test",
                    }
                }

            console.debug(JSON.stringify(jsonObj));
            $.ajax({
                dataType: "json",
                contentType:"application/json",
                mimeType: 'application/json',
                url:"<%=getTest%>",
                data:JSON.stringify(jsonObj),
                success : function(data) {
                    $("#ajaxResponse").html(data['testString']);
                }
            });

        }
    </script>

Controller side:

@ResourceMapping(value="ajaxTest")
    @ResponseBody
    public void ajaxTestMethod(ResourceRequest request, ResourceResponse response) throws IOException, ParseException {

        LOGGER.debug("ajax method");

        JSONObject json = JSONFactoryUtil.createJSONObject();
        json.put("testString", "Ik ben succesvol verstuurd geweest!");
        response.getWriter().write(json.toString());
}

How can I use the spring magic to auto map this JSON data to my own model? Note: It's Spring Portlet MVC, not regular Spring MVC..


回答1:


You need to build your json object like this:

var jsonObj = {
                user: "Korneel",
                password: "testpassword",
                "type.testParam" : "test"
            };

$.ajax({
            dataType: "json",
            contentType:"application/json",
            mimeType: 'application/json',
            url:"<%=getTest%>",
            data:jsonObj,
            success : function(data) {
                $("#ajaxResponse").html(data['testString']);
            }
        });

In your Controller you should use the @ModelAttribute annotation:

@ModelAttribute(value = "jsonObj")
public JsonObjCommand obtenerJsonObjCommand() {
    JsonObjCommand jsonObjCommand = new JsonObjCommand();
    return jsonObjCommand;
}

@ResourceMapping(value = "ajaxTest")
public void ajaxTestMethod(
        ResourceRequest request,
        ResourceResponse response,
        @ModelAttribute(value = "jsonObj") JsonObjCommand jsonObjCommand)
        throws IOException, ParseException {
    LOGGER.debug("USER: " + jsonObjCommand.getUser());
    LOGGER.debug("Password: " + jsonObjCommand.getPassword());
    LOGGER.debug("TestParam: " + jsonObjCommand.getType().getTestParam());
    LOGGER.debug("ajax method");

    JSONObject json = JSONFactoryUtil.createJSONObject();
    json.put("testString", "Ik ben succesvol verstuurd geweest!");
    response.getWriter().write(json.toString());
}

Don't forget your beans:

public class JsonObjCommand {

private String user;
private String password;
private TypeJson type;

public String getUser() {
    return user;
}
public void setUser(String user) {
    this.user = user;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
public TypeJson getType() {
    return type;
}
public void setType(TypeJson type) {
    this.type = type;
}

}

public class TypeJson {

private String testParam;

public String getTestParam() {
    return testParam;
}

public void setTestParam(String testParam) {
    this.testParam = testParam;
}

}



回答2:


@ResponseBody annotation is not supported out of the box in Spring MVC portlet framework, but you can implement @ResponseBody handling yourself.

We do it by implementing custom view type and model and view resolver.

  1. Implement custom model and view resolver (ModelAndViewResolver), let's say JsonModelAndViewResolver.
  2. In resolveModelAndView method, check whether controller method has @ResponseBody annotation (or more specific condition to identify JSON output - e.g. annotation + required supported mime type).
  3. If yes, return your custom View implementation - let's say SingleObjectJson view (extending AbstractView).
  4. Pass your to-be-serialized object to the view instance.
  5. The view will serialize the object to JSON format and write it to the response (by using Jackson, Gson or other framework in renderMergedOutputModel method).
  6. Register the new resolver as AnnotationMethodHandlerAdapter.customModelAndViewResolvers.



回答3:


According to the documentation, @RequestBody is only supported in Servlet environments, not Portlet environments (same for @ResponseBody). So it seems you can't use that functionality.



来源:https://stackoverflow.com/questions/28302074/resourcemapping-that-accepts-json-from-ajax-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!