为什么我不能更改 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结果之前处理数据。

PreResultListener

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
            }
       });
    }
   ...
}