Вопрос-ответ

Error: Could not find action or result No result defined for action action.Part and result {"col1":"col1","col2":"col2"}

Ошибка: не удалось найти действие или результат, результат не определен для action action.Часть и результат {"col1":"col1","col2": "col2"}

Я не получаю ответ в виде данных типа JSON с сервера.

Я использую плагин JSON.

jQuery( "#dialog-form" ).dialog({ 
autoOpen: false,
height: 500,
width: 750,
modal: true,
buttons :{
"Search" : function(){
jQuery.ajax({type : 'POST',
dataType : 'json',
url : '<s:url action="part" method="finder" />',
success : handledata})
}
}
});
var handledata = function(data)
{
alert(data);
}

Если dataType = 'json' я не получаю никакого ответа, но если я его не упоминаю dataType, я получаю формат страницы HTML.

public String list(){
JSONObject jo = new JSONObject();
try {
Iterator it = findList.iterator();
while(it.hasNext()){
SearchResult part = (SearchResult) it.next();
jo.put("col1",part.getcol1());
jo.put("col2",part.getcol2());
}
log.debug("--------->:"+jo.toString());
} catch (Exception e) {
log.error(e);
}
return jo.toString();
}

struts.xml:

<package name="default" namespace="/ajax" extends="json-default">
<action name="finder"
class="action.Part" method="finder" name="finder">

<result type="json" />
</action>
</package>

Страница JSP:

<div id="dialog-form" >
<form action="" id="channelfinder">
<textarea id="products" name="prodnbr"<s:property value='prodNbr'/>
</form>
</div>

Ошибка консоли:


org.apache.struts2.dispatcher.Dispatcher - Не удалось найти действие или результат, Результат не определен для действия action.Part и result {"col1":"col1","col2":"col2"}


web.xml:

    <?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>/parts</display-name>
<description>Parts List Web App</description>

<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>

<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>

<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.action</param-value>
</init-param>
</filter>


<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/errorPage.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/errorPage.jsp</location>
</error-page>

<!-- Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

</web-app>

Я не получаю данные для успешного выполнения jQuery.
Пожалуйста, поправьте меня, что здесь не так?

Переведено автоматически
Ответ 1

About Struts2-JSON Plugin

Struts2 JSON Plugin works in a particular way:


The JSON plugin provides a "json" result type that serializes actions into JSON.


It serializes the entire Action into JSON, except


  • transient properties

  • properties without the Getter

If you don't want the whole Action to be serialized, but only one object of your choice, you can specify a Root Object:


Use the "root" attribute(OGNL expression) to specify the root object to be serialized.


it can be done in struts.xml like this:

<result type="json">
<param name="root">
objectToBeSerialized
</param>
</result>

while the Action should have:

private CustomObject objectToBeSerialized;

public CustomObject getObjectToBeSerialized(){
return this.objectToBeSerialized;
}

Where CustomObject can be a Primitive, a String, an Array, etc...

Using it this way (the way it is built for), you can return SUCCESS and ERROR like in any other AJAX Struts2 Action, without breaking the framework conventions, and access the serialized JSON object from the callback function of the AJAX jQuery call like any other field (if using rootObject, the "data" of var handledata = function(data) would be your object, otherwise it would be your Action).


О вашем конкретном случае

В вашем случае, предполагая, что структура вашего объекта выглядит следующим образом

row1 [col1, col2], 
row2 [col1, col2],
rowN [col1, col2]

вы могли бы создать список объектов с двумя столбцами:

Объект значения

public class MyRow implements Serializable {
private static final long serialVersionUID = 1L;

private String col1;
private String col2;

// Getters
public String getCol1(){
return this.col1;
}
public String getCol2(){
return this.col2;
}
}

Класс Action

public class PartAction implements Serializable {
private static final long serialVersionUID = 1L;

private List<MyRow> rows;

// Getter
public List<MyRow> getRows() {
return this.rows;
}

public String finder() {
String result = Action.SUCCESS;
rows = new ArrayList<MyRow>();

try {
Iterator it = findList.iterator();
while(it.hasNext()) {
SearchResult part = (SearchResult) it.next();
MyRow row = new MyRow();
row.setCol1(part.getcol1());
row.setCol2(part.getcol2());
rows.add(row);
}
} catch (Exception e) {
result = Action.ERROR;
log.error(e);
}
return result;
}
}

Struts.xml

<package name="default" namespace="/ajax" extends="json-default">
<action name="finder" class="action.Part" method="finder" name="finder">
<result type="json" >
<param name="root">
rows
</param>
</result>
</action>
</package>

Чтобы протестировать это в функции обратного вызова AJAX, просто используйте $.each :

var handledata = function(data) {
$.each(data, function(index) {
alert(data[index].col1);
alert(data[index].col2);
});
}

Конечно, вы можете использовать List<List<String>> вместо пользовательского объекта или любой другой объектной структуры, которая вам нравится больше, чем эта: это было только для того, чтобы натолкнуть вас на идею.

Ответ 2

A dataType : 'json' используется jQuery Ajax для указания типа данных, который, как ожидается, будет возвращен success функцией обратного вызова при выполнении действия и результата, и ответа, возвращаемого с сервера.


dataType (по умолчанию: интеллектуальное предположение (xml, json, script или html))


Тип: String


Тип данных, которые вы ожидаете получить обратно от сервера. Если ничего не указано, jQuery попытается вывести это на основе MIME-типа ответа (MIME-тип XML выдаст XML, в версии 1.4 JSON выдаст объект JavaScript, в версии 1.4 script выполнит скрипт, а все остальное будет возвращено в виде строки).


URL-адрес должен правильно указывать на сопоставление действия. Предположим, что он будет в пространстве имен по умолчанию, в противном случае вам следует изменить URL и сопоставление, чтобы добавить атрибут namespace .

<script type="text/javascript">
$(function() {
$("#dialog-form").dialog ({
autoOpen: true,
height: 500,
width: 750,
modal: true,
buttons : {
"Search" : function() {
$.ajax({
url : '<s:url action="part" />',
success : function(data) {
//var obj = $.parseJSON(data);
var obj = data;
alert(JSON.stringify(obj));
}
});
}
}
});
});
</script>

Возвращаемый json тип результата не требуется, если вы создаете JSONObject вручную. Вы можете вернуть текст как результат потока, а затем преобразовать строку в JSON, если это необходимо.

struts.xml:

<package name="default" extends="struts-default">
<action name="part" class="action.PartAction" method="finder">
<result type="stream">
<param name="contentType">text/html</param>
<param name="inputName">stream</param>
</result>
</action>
</package>

Экшен:

public class PartAction extends ActionSupport {

public class SearchResult {
private String col1;
private String col2;

public String getCol1() {
return col1;
}

public void setCol1(String col1) {
this.col1 = col1;
}

public String getCol2() {
return col2;
}

public void setCol2(String col2) {
this.col2 = col2;
}

public SearchResult(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
}

private InputStream stream;

//getter here
public InputStream getStream() {
return stream;
}

private List<SearchResult> findList = new ArrayList<>();

public List<SearchResult> getFindList() {
return findList;
}

public void setFindList(List<SearchResult> findList) {
this.findList = findList;
}

private String list() {
JSONObject jo = new JSONObject();
try {
for (SearchResult part : findList) {
jo.put("col1", part.getCol1());
jo.put("col2", part.getCol2());
}
System.out.println("--------->:"+jo.toString());
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
return jo.toString();
}

@Action(value="part", results = {
@Result(name="stream", type="stream", params = {"contentType", "text/html", "inputName", "stream"}),
@Result(name="stream2", type="stream", params = {"contentType", "application/json", "inputName", "stream"}),
@Result(name="json", type="json", params={"root", "findList"})
})

public String finder() {
findList.add(new SearchResult("val1", "val2"));
stream = new ByteArrayInputStream(list().getBytes());
return "stream2";
}
}

Я поместил разные результаты с типом результата и типом содержимого, чтобы лучше описать идею. Вы могли бы вернуть любой из этих результатов и вернуть объект JSON в виде строки или нет. В строковой версии требуется проанализировать возвращаемые данные, чтобы получить объект JSON. Вы также можете выбрать, какой тип результата лучше сериализуется в соответствии с вашими потребностями, но моей целью было показать, что если вам нужно сериализовать простой объект, то для его работы не нужен плагин json.

Ссылки:

java json