为什么我不能更改 Struts2 的 valueStack?
Why can't I change the valueStack of Struts2?
我在拦截器中对Struts2的值栈做了一些操作,代码如下:
public String intercept(ActionInvocation actionInvocation) throws Exception {
String invokeRes = actionInvocation.invoke();
ValueStack valueStack = actionInvocation.getStack();
List<Object> shouldCheckFieldValues = Lists.newArrayList();
List<String> keywords = Lists.newArrayList("哈哈", "头部", "测试");
RegexKeywordFilter filter = new RegexKeywordFilter();
filter.add(keywords);
filter.compile();
final ReplaceStrategy highLightStrategy = new ReplaceStrategy() {
@Override
public String replaceWith(String keyword) {
return "<span style='background-color:red;'>" + keyword + "</span>";
}
};
Object respObj = valueStack.findValue("resp");
if (respObj instanceof JoyPageWebDTO) {
JoyPageWebDTO pageWebDTO = (JoyPageWebDTO) respObj;
List<?> recordsList = pageWebDTO.getRecords();
if (CollectionUtils.isNotEmpty(recordsList)) {
for (Object audit : recordsList) {
for (Field field : audit.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(AICheck.class)) {
boolean fieldIsAccess = field.isAccessible();
if (!fieldIsAccess) field.setAccessible(true);
Object fieldValue = field.get(audit);
if (fieldValue instanceof String && filter.hasKeywords((String) fieldValue)) {
String replacedStr = filter.replace((String) fieldValue, highLightStrategy);
field.set(audit, replacedStr);
}
if (!fieldIsAccess) field.setAccessible(false);
}
}
}
}
}
return invokeRes;
}
拦截前的值栈是:
[http://i.stack.imgur.com/SHqqD.png]
拦截后的valuestack为:
[http://i.stack.imgur.com/Ths7m.png]
拼接值堆栈有 changed.However,真正的 return 结果是:
{
"pageIndex": 0,
"pageSize": 30,
"recordCount": 0,
"records": [
{
"auditContent": "",
"auditID": 354,
"auditStatus": 3,
"bizStatus": 1,
"bodyPart": "2",
"categoryID": 141,
"city": "上海",
"desc": "22",
"duration": 2,
"forbidden": "2",
"indications": "2",
"name": "头部按摩很爽很爽"
}
]
}
我使用xml配置,代码如下:
<package name="ajax" namespace="/ajax" extends="json-default">
<interceptors>
<interceptor name="aiCheck"
class="com.dianping.joy.admin.web.interceptor.AICheckInterceptor">
</interceptor>
<interceptor-stack name="defaultInterceptorStack">
<interceptor-ref name="aiCheck" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defaultInterceptorStack"/>
<action name="searchJoySpu" class="com.action.SpuSearchAction">
<result type="json">
<param name="root">resp</param>
</result>
</action>
</package>
return结果不变。为什么以及如何更改此设置以获得更改后的结果?
您正在修改序列化后的对象,因此 JSON 包含旧值。
您可以在拦截器中使用PreResultListener
在执行json
结果之前处理数据。
A PreResultListener
can affect an action invocation between the
interceptor/action phase and the result phase. Typical uses include
switching to a different Result
or somehow modifying the Result
or
Action
objects before the Result
executes.
public class MyInterceptor extends AbstractInterceptor {
...
public String intercept(ActionInvocation invocation) throws Exception {
invocation.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation invocation,
String resultCode) {
// perform operation necessary before Result execution
}
});
}
...
}
我在拦截器中对Struts2的值栈做了一些操作,代码如下:
public String intercept(ActionInvocation actionInvocation) throws Exception {
String invokeRes = actionInvocation.invoke();
ValueStack valueStack = actionInvocation.getStack();
List<Object> shouldCheckFieldValues = Lists.newArrayList();
List<String> keywords = Lists.newArrayList("哈哈", "头部", "测试");
RegexKeywordFilter filter = new RegexKeywordFilter();
filter.add(keywords);
filter.compile();
final ReplaceStrategy highLightStrategy = new ReplaceStrategy() {
@Override
public String replaceWith(String keyword) {
return "<span style='background-color:red;'>" + keyword + "</span>";
}
};
Object respObj = valueStack.findValue("resp");
if (respObj instanceof JoyPageWebDTO) {
JoyPageWebDTO pageWebDTO = (JoyPageWebDTO) respObj;
List<?> recordsList = pageWebDTO.getRecords();
if (CollectionUtils.isNotEmpty(recordsList)) {
for (Object audit : recordsList) {
for (Field field : audit.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(AICheck.class)) {
boolean fieldIsAccess = field.isAccessible();
if (!fieldIsAccess) field.setAccessible(true);
Object fieldValue = field.get(audit);
if (fieldValue instanceof String && filter.hasKeywords((String) fieldValue)) {
String replacedStr = filter.replace((String) fieldValue, highLightStrategy);
field.set(audit, replacedStr);
}
if (!fieldIsAccess) field.setAccessible(false);
}
}
}
}
}
return invokeRes;
}
拦截前的值栈是:
[http://i.stack.imgur.com/SHqqD.png]
拦截后的valuestack为:
[http://i.stack.imgur.com/Ths7m.png]
拼接值堆栈有 changed.However,真正的 return 结果是:
{
"pageIndex": 0,
"pageSize": 30,
"recordCount": 0,
"records": [
{
"auditContent": "",
"auditID": 354,
"auditStatus": 3,
"bizStatus": 1,
"bodyPart": "2",
"categoryID": 141,
"city": "上海",
"desc": "22",
"duration": 2,
"forbidden": "2",
"indications": "2",
"name": "头部按摩很爽很爽"
}
]
}
我使用xml配置,代码如下:
<package name="ajax" namespace="/ajax" extends="json-default">
<interceptors>
<interceptor name="aiCheck"
class="com.dianping.joy.admin.web.interceptor.AICheckInterceptor">
</interceptor>
<interceptor-stack name="defaultInterceptorStack">
<interceptor-ref name="aiCheck" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="defaultInterceptorStack"/>
<action name="searchJoySpu" class="com.action.SpuSearchAction">
<result type="json">
<param name="root">resp</param>
</result>
</action>
</package>
return结果不变。为什么以及如何更改此设置以获得更改后的结果?
您正在修改序列化后的对象,因此 JSON 包含旧值。
您可以在拦截器中使用PreResultListener
在执行json
结果之前处理数据。
A
PreResultListener
can affect an action invocation between the interceptor/action phase and the result phase. Typical uses include switching to a differentResult
or somehow modifying theResult
orAction
objects before theResult
executes.public class MyInterceptor extends AbstractInterceptor { ... public String intercept(ActionInvocation invocation) throws Exception { invocation.addPreResultListener(new PreResultListener() { public void beforeResult(ActionInvocation invocation, String resultCode) { // perform operation necessary before Result execution } }); } ... }