使用@ResourceMapping 和@ModelAttribute 访问 Spring Portlet Controller 内的 RequestBody
Access RequestBody inside Spring Portlet Controller using @ResourceMapping and @ModelAttribute
我的问题类似于下面的post:
JSON ajax POST to Spring Portlet Controller @ResourceMapping conversion issue and
我在那里尝试过Tipps,但没有成功。
我有以下技术:
- liferay-门户 6.2 CE
- 基于 spring 3.0.7
的 liferay 自定义 portlet 插件
- kendo-ui 对于 jsp
在客户端,我为 jsp 生成了一个字符串化的 json-Object,它具有 kendo-ui 的功能,并在请求正文中提交.目前它只包含一些过滤器参数(但它也可以包含用于服务器端分页、排序、分组等的其他参数)。
在 Firefox 开发人员工具中,请求正文(有效负载)如下所示:
{
"filter" : {
"logic" : "and",
"filters" : [{
"field" : "name",
"value" : ""
}, {
"field" : "city",
"value" : ""
}, {
"field" : "zip",
"value" : ""
}, {
"field" : "country",
"value" : ""
}
]
}
}
在服务器端,我有一个用于该结构的 POJO。我在 Spring Web MVC Servlet 环境中测试成功。使用 @RequestBody 和 Jackson 可以反序列化 JSON 对象。
在 liferay-portlet 环境中工作 我不能使用 @RequestBody 和 httpServletRequest。
控制器如下所示:
@ResourceMapping(value = "test")
public void searchProviderTest(ResourceRequest request, ResourceResponse response,
@ModelAttribute("filter") DataSourceRequest dataSourceRequest) {
LOGGER.info(">>>>>> JsonOjekt per Parameter übergeben: " + request.getParameter("filter"));
LOGGER.info(">>>>>>>> DatasourceRequest: " + dataSourceRequest);
}
DataRequestObject 没有值。我看到了所有属性,但它们是空的。并且没有请求参数"filter"(如预期的那样)
这是我的 DataSourceRequest-Object(摘要):
public class DataSourceRequest {
private int page;
private int pageSize;
private int take;
private int skip;
private List<SortDescriptor> sort;
private List<GroupDescriptor> group;
private List<AggregateDescriptor> aggregate;
private HashMap<String, Object> data;
private FilterDescriptor filter;
public DataSourceRequest() {
filter = new FilterDescriptor();
data = new HashMap<String, Object>();
}
...(getters and setters)
public static class FilterDescriptor {
private String logic;
private List<FilterDescriptor> filters;
private String field;
private Object value;
private String operator;
private boolean ignoreCase = true;
public FilterDescriptor() {
filters = new ArrayList<FilterDescriptor>();
}
...(getters and setters)
几周以来我一直在寻找解决方案,但我没有使用 portlet 控制器将 JSON-Object 转换(反序列化?)为 DataSourceRequest-Object。我什至不知道如何从 portlet 控制器访问请求正文(有效负载)中的 JSON-String。
在 第二次提到 post 之后,嵌套对象 可能是问题所在。我联系了 kendo-ui 支持人员,询问如何提交请求以获取 post 中描述的格式。但是他们告诉我,这是不可能的(例如使用数据源对象的参数映射属性),我必须在服务器端解决它。
首先post描述了一个解决方案@ModelAttribute,但后来我只得到了空对象——当我尝试使用 @RequestParam 获取 JSON 我收到一个错误,该参数不在请求中(我认为是因为它在正文中)
我正在考虑基于 Spring Web MVC Servlet 设置一个 额外的 RESTFul API - 我什至试过了它有效-但我不确定这是否真的有意义,因为 liferay 已经有一个 RESTFul -API.
有没有办法将 JSON 对象转换为 Portlet 控制器内的 JAVA 对象? 或 我需要额外的 API?
欢迎任何提示!!
我在使用 Liferay 序列化和反序列化 Json 时遇到了同样的问题。我的解决方案是将 json 作为表单数据中的参数发送。这样我就可以使用以下方法检索 Json:
String paramJson = ParamUtil.getString(request, "myJson");
然后利用Gsonapi反序列化:
new Gson().fromJson(paramJson, MyPOJO.class);
有了Gson你就不会有那么多烦恼了。
您还可以使用 Gson 序列化服务 return 中的对象,这将避免嵌套对象出现问题 Liferay 无法正确序列化。
此代码显示如何发送 Json 作为请求正文:
请求将由 MVCPortlet 中的方法 'serveResource' 处理。
var portletUrl = Liferay.PortletURL.createResourceURL();
portletUrl.setPortletId(<portletId>);
portletUrl.setResourceId('publicar'); // Any identifier
var formData = new FormData();
formData.append(<portlet-namespace> + 'myJson', JSON.stringify(object));
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', callbackSuccess, false);
xhr.open('POST', urlPortlet);
xhr.send(formData);
要分享我的经验,请按以下步骤操作:
在 JS 中将 contentType 设置为 application/x-www-form-urlencoded。那是 kendo-ui 的代码(在后台使用 jQuery Ajax)
<kendo:dataSource-transport-parameterMap>
function parameterMap(options,type) {
if(type==="read"){
return "osdeFilter=" + encodeURIComponent(JSON.stringify(options));
} else {
return "osdeModels=" + encodeURIComponent(JSON.stringify(options.models));
}
}
</kendo:dataSource-transport-parameterMap>
获取参数,在我的例子中使用 Jackson 手动反序列化 JSON String
@ResourceMapping(value = "test")
public void searchProviderTest(ResourceRequest request, ResourceResponse response)
throws JsonParseException, JsonMappingException, IOException {
String osdeFilter = URLDecoder.decode(request.getParameter("osdeFilter"),"UTF-8");
LOGGER.info(">>>>>> JsonOjekt per Parameter übergeben: " + request.getParameter("osdeFilter"));
ObjectMapper objectMapper = new ObjectMapper();
DataSourceRequest dataSourceRequest = objectMapper.readValue(osdeFilter, DataSourceRequest.class);
LOGGER.info(">>>>>>>> DatasourceRequest: " + dataSourceRequest);
}
与@giovani 不同,我不需要提交 portlet 命名空间。为此,您必须将以下配置添加到 liferay-portlet.xml
<requires-namespaced-parameters>false</requires-namespaced-parameters>
我的问题类似于下面的post:
JSON ajax POST to Spring Portlet Controller @ResourceMapping conversion issue and
我在那里尝试过Tipps,但没有成功。 我有以下技术:
- liferay-门户 6.2 CE
- 基于 spring 3.0.7 的 liferay 自定义 portlet 插件
- kendo-ui 对于 jsp
在客户端,我为 jsp 生成了一个字符串化的 json-Object,它具有 kendo-ui 的功能,并在请求正文中提交.目前它只包含一些过滤器参数(但它也可以包含用于服务器端分页、排序、分组等的其他参数)。
在 Firefox 开发人员工具中,请求正文(有效负载)如下所示:
{
"filter" : {
"logic" : "and",
"filters" : [{
"field" : "name",
"value" : ""
}, {
"field" : "city",
"value" : ""
}, {
"field" : "zip",
"value" : ""
}, {
"field" : "country",
"value" : ""
}
]
}
}
在服务器端,我有一个用于该结构的 POJO。我在 Spring Web MVC Servlet 环境中测试成功。使用 @RequestBody 和 Jackson 可以反序列化 JSON 对象。
在 liferay-portlet 环境中工作 我不能使用 @RequestBody 和 httpServletRequest。
控制器如下所示:
@ResourceMapping(value = "test")
public void searchProviderTest(ResourceRequest request, ResourceResponse response,
@ModelAttribute("filter") DataSourceRequest dataSourceRequest) {
LOGGER.info(">>>>>> JsonOjekt per Parameter übergeben: " + request.getParameter("filter"));
LOGGER.info(">>>>>>>> DatasourceRequest: " + dataSourceRequest);
}
DataRequestObject 没有值。我看到了所有属性,但它们是空的。并且没有请求参数"filter"(如预期的那样)
这是我的 DataSourceRequest-Object(摘要):
public class DataSourceRequest {
private int page;
private int pageSize;
private int take;
private int skip;
private List<SortDescriptor> sort;
private List<GroupDescriptor> group;
private List<AggregateDescriptor> aggregate;
private HashMap<String, Object> data;
private FilterDescriptor filter;
public DataSourceRequest() {
filter = new FilterDescriptor();
data = new HashMap<String, Object>();
}
...(getters and setters)
public static class FilterDescriptor {
private String logic;
private List<FilterDescriptor> filters;
private String field;
private Object value;
private String operator;
private boolean ignoreCase = true;
public FilterDescriptor() {
filters = new ArrayList<FilterDescriptor>();
}
...(getters and setters)
几周以来我一直在寻找解决方案,但我没有使用 portlet 控制器将 JSON-Object 转换(反序列化?)为 DataSourceRequest-Object。我什至不知道如何从 portlet 控制器访问请求正文(有效负载)中的 JSON-String。
在 第二次提到 post 之后,嵌套对象 可能是问题所在。我联系了 kendo-ui 支持人员,询问如何提交请求以获取 post 中描述的格式。但是他们告诉我,这是不可能的(例如使用数据源对象的参数映射属性),我必须在服务器端解决它。
首先post描述了一个解决方案@ModelAttribute,但后来我只得到了空对象——当我尝试使用 @RequestParam 获取 JSON 我收到一个错误,该参数不在请求中(我认为是因为它在正文中)
我正在考虑基于 Spring Web MVC Servlet 设置一个 额外的 RESTFul API - 我什至试过了它有效-但我不确定这是否真的有意义,因为 liferay 已经有一个 RESTFul -API.
有没有办法将 JSON 对象转换为 Portlet 控制器内的 JAVA 对象? 或 我需要额外的 API?
欢迎任何提示!!
我在使用 Liferay 序列化和反序列化 Json 时遇到了同样的问题。我的解决方案是将 json 作为表单数据中的参数发送。这样我就可以使用以下方法检索 Json:
String paramJson = ParamUtil.getString(request, "myJson");
然后利用Gsonapi反序列化:
new Gson().fromJson(paramJson, MyPOJO.class);
有了Gson你就不会有那么多烦恼了。 您还可以使用 Gson 序列化服务 return 中的对象,这将避免嵌套对象出现问题 Liferay 无法正确序列化。
此代码显示如何发送 Json 作为请求正文:
请求将由 MVCPortlet 中的方法 'serveResource' 处理。
var portletUrl = Liferay.PortletURL.createResourceURL();
portletUrl.setPortletId(<portletId>);
portletUrl.setResourceId('publicar'); // Any identifier
var formData = new FormData();
formData.append(<portlet-namespace> + 'myJson', JSON.stringify(object));
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', callbackSuccess, false);
xhr.open('POST', urlPortlet);
xhr.send(formData);
要分享我的经验,请按以下步骤操作:
在 JS 中将 contentType 设置为 application/x-www-form-urlencoded。那是 kendo-ui 的代码(在后台使用 jQuery Ajax)
<kendo:dataSource-transport-parameterMap> function parameterMap(options,type) { if(type==="read"){ return "osdeFilter=" + encodeURIComponent(JSON.stringify(options)); } else { return "osdeModels=" + encodeURIComponent(JSON.stringify(options.models)); } } </kendo:dataSource-transport-parameterMap>
获取参数,在我的例子中使用 Jackson 手动反序列化 JSON String
@ResourceMapping(value = "test") public void searchProviderTest(ResourceRequest request, ResourceResponse response) throws JsonParseException, JsonMappingException, IOException { String osdeFilter = URLDecoder.decode(request.getParameter("osdeFilter"),"UTF-8"); LOGGER.info(">>>>>> JsonOjekt per Parameter übergeben: " + request.getParameter("osdeFilter")); ObjectMapper objectMapper = new ObjectMapper(); DataSourceRequest dataSourceRequest = objectMapper.readValue(osdeFilter, DataSourceRequest.class); LOGGER.info(">>>>>>>> DatasourceRequest: " + dataSourceRequest); }
与@giovani 不同,我不需要提交 portlet 命名空间。为此,您必须将以下配置添加到 liferay-portlet.xml
<requires-namespaced-parameters>false</requires-namespaced-parameters>