can't set Struts2 result type to json - json

I want to use json with Struts2. However, when I set the action return type to "json", I got "there is no result type defined for type 'json' mapped with name 'success'." Bellow is struts.xml file.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.custom.i18n.resources" value="resource"/>
<package extends="struts-default" name="test">
<action name="inputHandler" class="inputHandlerAction">
<result name="input">/index.jsp</result>
<result>/result.jsp</result>
</action>
<action name="setLangHandler" class="com.sesoft.test.setLanguageHandler">
<result>/index.jsp</result>
</action>
<action name="Handler" class="com.sesoft.test.Handler">
<result>/test2.jsp</result>
</action>
</package>
<package name="example" extends="json-default">
<action name="ajaxHandler" class="com.sesoft.test.AjaxHandler">
<result name="success" type="json" />
</action>
</package>
</struts>
Before I added the json Action, all other action performs fine. But after I added the json Action, the server failed to action with error code 503.
libs I've added "jsonplugin-0.33.jar" to the lib directory.

You don't have the JSON result defined in your struts.xml package. If you only need default things then you can just extend json-default instead of struts-default. If you need to customise the package then include the following and that should do the trick:
<result-types>
<result-type name="json" class="com.googlecode.jsonplugin.JSONResult"/>
</result-types>

you package should extends json-default
<package name="json-default" extends="struts-default">
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
<interceptors>
<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
</interceptors>
</package>

If using Maven you may need to add the dependency e.g.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.2.3</version>
</dependency>

Here is my configuration in pom.xml:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.1.2</version>
</dependency>
In the action result you only need to specify type="json" :
<result type="json"/>
Remember the variable getter and setter in type="json" response give getters in the action.

Include json-default in the extends parameter:
<package name="default" extends="struts-default,json-default">
<action>
...
...
</action>
</package>

Related

My own block class defined in community cood pool. But it not work with relevant template (Magento version 1.9 extension development)

I try to create small extension for displaying string in Product page Magento 1.9.2. So I did it using "community" code pool for effecting block (block name ="product.info") in catalog.xml layout but it did not work till. I think my code is right but I don't sure whether all relevant folders (Controller, helper, Observer) are included or not in my module(Dinod). Please any one can help me to create this extension by using "community" code pool in Magento 1.9.2.
I failed to get expected output by testing my extension using "community" code pool. But same extension structure work fine after using "core" code pool. So I stored my module(Dinod) inside "app/code/core/Mage" folder and that time worked properly.
This code structure does not generate any expected output through frontend (product page).
app/etc/modules/Jpdn_Dinod.xml
<config>
<modules>
<Jpdn_Dinod>
<active>true</active>
<codePool>community</codePool>
</Jpdn_Dinod>
</modules>
</config>
app/code/community/Jpdn/Dinod/etc/config.xml
<config>
<modules>
<Jpdn_Dinod>
<version>1.0.3</version>
</Jpdn_Dinod>
</modules>
<frontend>
<layout>
<updates>
<Jpdn_Dinod module="Jpdn_Dinod">
<file>jpdn_dinod.xml</file>
</Jpdn_Dinod>
</updates>
</layout>
</frontend>
<global>
<!-- adding block "Jpdn_Dinod_Block_Product_View" -->
<blocks>
<jpdn_dinod>
<class>Jpdn_Dinod_Block_Product_View</class>
</jpdn_dinod>
</blocks>
<!-- adding block "Jpdn_Dinod_Block_Product_View" -->
</global>
</config>
app/code/community/Jpdn/Dinod/Block/Product/View/dinod.php
class Jpdn_Dinod_Block_Product_View_Dinod extends Mage_Core_Block_Template
{
public function dinod_methodblock()
{
$name = "Informations from dinod_methodblock in Jpdn_Dinod";
return $name;
}
}
app/design/frontend/base/default/layout/jpdn_dinod.xml
<layout version="1.0.3">
<catalog_product_view>
<reference name="product.info">
<!--
<block type="dinod/product_view_dinod" name="mage.view.dinod" as="mage.dinod" template="dinod/product/view/dinod.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Dinodddd works</value></action>
</block>
-->
<block type="jpdn_dinod/product_view_dinod" name="jpdn.view.dinod" as="jpdn.dinod" template="dinod/product/view/dinod.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Dinodddd works</value></action>
</block>
</reference>
</catalog_product_view>
</layout>
app/design/frontend/base/default/template/dinod/product/view/dinod.phtml
<?php echo $this->dinod_methodblock(); ?>
Above code structure does not generate any expected output through frontend (product page).
After I created new block class file in "app/code/core/Mage" and edited code in template file as below so I got expected output without any error.
app/code/core/Mage/Dinod/Block/Product/View/dinod.php
class Mage_Dinod_Block_Product_View_Dinod extends Mage_Core_Block_Template
{
public function dinod_methodblock()
{
$name = "Informations from dinod_methodblock in Mage_Dinod";
return $name;
}
}
app/design/frontend/base/default/layout/jpdn_dinod.xml
<layout version="1.0.3">
<catalog_product_view>
<reference name="product.info">
<block type="dinod/product_view_dinod" name="mage.view.dinod" as="mage.dinod" template="dinod/product/view/dinod.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Dinodddd works</value></action>
</block>
<block type="jpdn_dinod/product_view_dinod" name="jpdn.view.dinod" as="jpdn.dinod" template="dinod/product/view/dinod.phtml">
<action method="addToParentGroup"><group>detailed_info</group></action>
<action method="setTitle" translate="value"><value>Dinodddd works</value></action>
</block>
</reference>
</catalog_product_view>
</layout>
But I want to get same output only using "community" code pool instead of using "core" code pool for effecting block (block name ="product.info") in catalog.xml layout.
Your block definition is wrong
<blocks>
<jpdn_dinod>
<class>Jpdn_Dinod_Block_Product_View</class>
</jpdn_dinod>
</blocks>
this is not how you should declare it. Remove product_view
<class>Jpdn_Dinod_Block</class>
this should be enough

log4j2 exception handling not working

I am using log4j2 with this 2 dependencies:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.6.2</version>
</dependency>
When I try to log for example an error with a throwable like:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.annotations.Test;
public class Test {
private static final Logger logger = LogManager.getLogger(Test.class);
#Test
public void testSendMessage() throws Exception {
Exception exception = new Exception("some exception");
logger.error("error with exception", exception);
}
}
using patternlayout:
<Configuration>
<properties>
<property name="filters">org.testng,org.apache.maven,sun.reflect,java.lang.reflect</property>
</properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" direct="true">
<PatternLayout pattern="%maxLen{%d{DEFAULT} [%p] %c{-3}:%L - %enc{%m} %xEx{filters(${filters})}%n}{200}"/>
</Console>
</Appenders>
<Loggers>
<logger name="my.test.class.path" level="trace" additivity="false">
<AppenderRef ref="ConsoleAppender" />
</logger>
</Loggers>
</Configuration>
Then the filtered packages won't disappear from the stacktrace, I can't even manipulate the stacktrace in any way like maximizing the lines:
%xEx{5}
Highlightning also don't work in eclipse nor in Kibana(ELK environment).
Can anybody help?
Could it be that the %xEx PatternLayout converter doesn't support property substitution in its options?
What if you put the packages you want to filter directly in the filters list?
It may be worth raising a Jira ticket on the Log4j 2 issue tracker for this.
try to remove the ending{200}. i think there is an issue using more sub parameters.
here is a snippet which works. please note if you add additional things like separator(|) it will stop working [tested in version 2.8.1 and 2.9.1]
<Properties>
<Property name="exfilters">org.jboss,java.lang.reflect,sun.reflect</Property>
<Property name="log-pattern">%d %-5p %m%n%xEx{filters(${exfilters})}/Property>
</Properties>
...
<PatternLayout pattern="${sys:log-pattern}"/>
Works for me on Log4j2 v 2.17 (and also for rThrowable):
<Properties>
<Property name="PACKAGE_FILTER">org.jboss,java.lang.reflect,sun.reflect</Property>
<Property name="LOG_PATTERN">%xThrowable{filters(${PACKAGE_FILTER})}</Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
</Appenders>

Parent package is not defined : jfreechart-default [Unknown Location]

I am trying use Struts2 jfreechart plugin - using a Maven project.
In Maven dependencies I am able to see the jfree-chart jar file.
DO I need to use a separate package?
Getting following error:
SEVERE: Dispatcher initialization failed
Unable to load configuration. - [unknown location]
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:70)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:967)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:435)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:479)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:57)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4828)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5508)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: Parent package is not defined: jfreechart-default - [unknown location]
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.buildPackageContext(XmlConfigurationProvider.java:674)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:523)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:295)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:264)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
... 17 more
My struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true"></constant>
<package name="basicstruts2" extends="struts-default, jfreechart-default">
<action name="index">
<result>/index.jsp</result>
</action>
<action name="getchart" class="com.struts.charts.actions.ChartAction"
method="execute">
<result name="success" type="chart">
<param name="width">400</param>
<param name="height">300</param>
</result>
</action>
</package>
</struts>
In the struts.xml you have used the code that requires struts2-jfreechart-plugin-x.x.x.jar to be on classpath. This plugin has struts-plugin.xml where the jfreechart-default package is defined. You need this if your package extends jfreechart-default.
<package name="basicstruts2" extends="struts-default, jfreechart-default">

Is there a convenient way to configure noCache and excludeNullProperties parameters for json result in struts2?

I am using struts-json-plugin.2.2.3 for Actions whose result type is json, here is an demo configuration:
<action name="dept_*" class="com.XXX.action.DepartmentAction" method="{1}">
<result name="search">dept_search.jsp</result>
<result name="search_ajax" type="json"><param name="root">deptList</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
<result name="save" type="json"><param name="root">jsonResult</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
<result name="count" type="json"><param name="root">pageCount</param><param name="excludeNullProperties">true</param><param name="noCache">true</param></result>
</action>
This configuration works fine. But for all Actions in my project, noCache and excludeNullProperties have same configuration value just like code above, so I am searching a way to configure them in one place and used for all. I find in JSONInterceptor class, there are same name properties, so I configured like this:
<interceptors>
<interceptor-stack name="ecsStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="json"><param name="noCache">true</param><param name="excludeNullProperties">true</param><param name="contentType">application/json;charset=utf-8</param></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="ecsStack"></default-interceptor-ref>
And remove same configurations in Action result, but it does not work as expected, there is no cache-control, expires and pragma information in response headers, and null properties are sent to browser.
So why it does not work?
If there is a convenient way to configure these two parameters?
Try this result-type configuration in struts.xml file:
<result-type name="json" class="org.apache.struts2.json.JSONResult">
<param name="noCache">true</param>
<param name="excludeNullProperties">true</param>
</result-type>

Struts 2 jquery autocompleter with JSON

I'm using atocompleter in my form with json.
This is the part of my struts.xml
<package name="json" namespace="/" extends="json-default">
<result-types>
<result-type name="json" class="com.googlecode.jsonplugin.JSONResult" />
</result-types>
<action name="test" class="testClass" method="populate">
<result type="json" name="success">
<param name="root">itemList</param>
<param name="contentType">text/html</param>
</result>
</action>
</package>
This is the jsp
<s:form id="frm_demo" name="frm_demo" theme="simple" action="test2">
<s:url id="remoteurl" action="test" />
<sj:autocompleter
id="lst"
name="lst"
list="%{remoteurl}"
listValue="name"
listKey="id"
selectBox="true"
/>
<s:submit value="submit"/>
</s:form>
This is the action class method
public String populate() throws Exception{
itemList.put("1", "a");
itemList.put("2", "b");
itemList.put("3", "c");
return "success";
}
With the above code in struts.xml my jsp renders like this.{"3":"c","2":"b","1":"a"}
But when I delete the "contentType" parameter, in other words the content type is "application/json" the jsp pops the download window.
I need theauto completer to return the key when i click submit button. But the page doesn't load with the autocompleter. Any solutions?
p.s. itemList i used in my action class is a HashMap... does that matter?
Using map is OK with collection-backed components. I think there's couple of problems with your code.
First in you action configuration you have set the root object to your itemList, this way only content of the list will be converted to json so you can't refer to the list itself in your autocompleter.
Second you have to set the href attribute for your autocompleter and set the remoteUrl as it's value. So your code could be like:
<package name="json" namespace="/" extends="json-default">
<action name="test" class="testClass" method="populate">
<result type="json"/>
</action>
</package>
In your autompleter:
<s:form id="frm_demo" theme="simple" action="test2">
<s:url id="remoteurl" action="test" />
<sj:autocompleter href="%{remoteurl}"
id="lst"
name="lst"
list="itemList"
listValue="name"
listKey="id"
selectBox="true"/>
<s:submit value="submit"/>
</s:form>
See if that works.
I think your code is ok,Just remove this code
<param name="contentType">text/html</param>