Spring MVC: ModelAndViewContainer: представление равно [null]; модель по умолчанию {Some-Object}

Я использую Spring-mvc с ContentNegotiatingViewResolver для обработки моих объектов ответа и анализа в определенном формате. Когда я возвращаю объект из контроллера, в ответ он добавляет мой объект ответа, но также добавляет объект, который я использовал для сопоставления параметра запроса. Мой контроллер действует как контроллер отдыха. Потому что я хочу создать службы отдыха, используя spring с ContentNegotiatingViewResolver. После отладки я нашел класс InvocableHandlerMethdod, в котором метод invokeForRequest содержит следующий аргумент:

public final Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
        Object... providedArgs) throws Exception {
  ...............................................

В аргументе ModelAndViewContainer содержится следующая деталь:

ModelAndViewContainer: View is [null]; default model {oauthClientDetail=com.netsol.entities.OauthClientDetail@9ac35e, org.springframework.validation.BindingResult.oauthClientDetail=org.springframework.validation.BeanPropertyBindingResult: 0 errors}

Я не могу понять, почему объект OauthClientDetail установлен в ModelAndViewContainer и как я могу предотвратить это.

Ниже приведен код моего контроллера:

@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
public ApiResponse<UserDetail> changePassword(@Valid OauthClientDetail clientDetail,
        BindingResult bindingResult,
        @RequestParam(value = "password", required = true) String password) {
    logger.info("In changePassword Service...... ");

    if(bindingResult.hasErrors()){
        throw new InvalidRequestException("Error", bindingResult);
    }

    UserDetail detail = userService.changeUserPassword(password, clientDetail, encoder);
    ApiResponse<UserDetail> response = new ApiResponse<UserDetail>();
    if(detail != null){
        response.setErrorCode(CommonUtility.API_RESPONSE_STATUS.SUCCESS.getValue());
        response.setErrorMessage(CommonUtility.API_RESPONSE_STATUS.SUCCESS.getMessage());
        response.setResponse(detail);
    }else{
        response.setErrorCode(CommonUtility.API_RESPONSE_STATUS.FAIL.getValue());
        response.setErrorMessage(CommonUtility.API_RESPONSE_STATUS.FAIL.getMessage());
        response.setResponse(null);
    }
    return response; 
}

Конфигурация rest-servlet.xml:

 bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="parameterName" value="mediaType" />
    <property name="ignoreAcceptHeader" value="true" />
    <property name="useJaf" value="false" />
    <property name="defaultContentType" value="application/json" />

    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </map>
    </property>
</bean>

<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="contentNegotiationManager" ref="contentNegotiationManager" />
    <property name="order" value="1" />
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
            <entry key="html" value="text/html" />
        </map>
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />

            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                        <property name="autodetectAnnotations" value="true" />
                        <property name="aliases">
                            <map>
                                <entry key="list" value="java.util.List" />
                                <entry key="string" value="java.lang.String" />
                                <entry key="hsahmap" value="java.util.HashMap" />
                                <entry key="object" value="java.lang.Object" />
                                <entry key="hashSet" value="java.util.HashSet" />
                            </map>
                        </property>
                        <property name="supportedClasses">
                            <list>
                                <value>java.util.List</value>
                                <value>java.lang.String</value>
                                <value>java.util.Map</value>
                                <value>java.lang.Object</value>
                                <value>java.util.Set</value>
                                <value>java.lang.Long</value>
                                <value>java.util.Date</value>
                            </list>
                        </property>
                    </bean>
                </constructor-arg>
            </bean>
        </list>
    </property>
    <property name="defaultContentType" ref="htmlMediaType" />
    <property name="ignoreAcceptHeader" value="true" />
</bean>

<bean id="htmlMediaType" class="org.springframework.http.MediaType">
    <constructor-arg value="text" />
    <constructor-arg value="html" />
</bean>

Мой запрос от клиента chrome postman:

POST /empirecl-api/api/changePassword HTTP/1.1
Host: localhost:8080
Authorization: Bearer b3f46274-b019-4d7b-a3bd-5c19e9660c2f
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

clientId=my-client-with-secret&clientSecret=12345678&clientSecretConfirm=12345678&password=12345678

Мой ответ:

{
"oauthClientDetail": {
    "userId": null,
    "clientId": "my-client-with-secret",
    "additionalInformation": null,
    "authorities": null,
    "authorizedGrantTypes": null,
    "autoapprove": null,
    "clientSecret": "12345678",
    "clientSecretConfirm": "12345678",
    "resourceIds": null,
    "scope": null,
    "webServerRedirectUri": null,
    "createdOn": null,
    "updatedOn": null,
    "active": null,
    "lastLogin": null
},
"apiResponse": {
    "errorCode": 0,
    "errorMessage": "Success",
    "response": {
        "userName": "my-client-with-secret",
        "dateCreated": null,
        "dateUpdated": null,
        "active": "true"
    }
}
}

В ответ объект oauthClientDetail содержит значения, которые я отправляю с запросом и сопоставляю с объектом. Исходя из этого, я предполагаю, что мой объект карты установлен в ответе. Как я могу предотвратить установку этого объекта в ответ.


person Harmeet Singh Taara    schedule 30.07.2014    source источник


Ответы (1)


Я нашел решение по этой ссылке MappingJacksonJsonView возвращает объект json верхнего уровня. Нужно добавить аннотацию @ResponseBody в контроллер и установить produces={"application/json"}. Следующий мой новый код:

 @RequestMapping(value = "/changePassword", method = RequestMethod.POST, produces={"application/json"})
public @ResponseBody ApiResponse<UserDetail> changePassword(@Valid OauthClientDetail clientDetail,
        BindingResult bindingResult,
        @RequestParam(value = "password", required = true) String password) {
    logger.info("In changePassword Service...... ");

    if(bindingResult.hasErrors()){
        throw new InvalidRequestException("Error", bindingResult);
    }

    UserDetail detail = userService.changeUserPassword(password, clientDetail, encoder);
    ApiResponse<UserDetail> response = new ApiResponse<UserDetail>();
    if(detail != null){
        response.setSuccess(CommonUtility.API_RESPONSE_STATUS.SUCCESS.getValue());
        response.setMessage(CommonUtility.API_RESPONSE_STATUS.SUCCESS.getMessage());
        response.setResponse(detail);
    }else{
        response.setSuccess(CommonUtility.API_RESPONSE_STATUS.FAIL.getValue());
        response.setMessage(CommonUtility.API_RESPONSE_STATUS.FAIL.getMessage());
        response.setResponse(null);
    }
    return response; 
}
person Harmeet Singh Taara    schedule 30.07.2014