yonney.yang
yonney.yang

Reputation: 135

Why can't I change the valueStack of Struts2?

I do some operation of Struts2's value stack in an interceptor,code like this:

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

The valuestack before intercept is :

[https://i.sstatic.net/SHqqD.png]

The valuestack after intercept is:

[https://i.sstatic.net/Ths7m.png]

It's seamed the valuestack has changed.However,the really return result is:

{
"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": "头部按摩很爽很爽"
 }
]
}

I use xml config,code like this:

<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>

The return result is not changed. Why and how can I change this get the changed result?

Upvotes: 2

Views: 270

Answers (1)

Roman C
Roman C

Reputation: 1

You are modifying the object after it has been serialized, so JSON contains the old value.

You can use PreResultListener in the interceptor to handle data before json result is executed.

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

Upvotes: 3

Related Questions