Spring RestTemplate交换抛出UnhandledHttpStatusException

时间:2016-06-24 06:16:36

标签: java spring exception resttemplate

概述: 我将使用RestTemplate从外部REST Web服务调用get请求。

我的代码如下:

@Slf4j
@Component("AccMemberDetailsApiControllerImpl")
public class AccMemberDetailsApiControllerImpl implements MemberDetailsApiController {

    private static final String CONTENT_TYPE_HEADER_NAME = "Content-Type";
    private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
    private static final String USERID_PARAMETER_NAME = "userId";
    private static final String VEHICLEID_PARAMETER_NAME = "vehicleId";

    private static final ObjectMapper mapper = new ObjectMapper();

    /**
     * This constant is used to check whether or not the response from ACC is an empty JSON string
     */
    private static final String EMPTY_RESPONSE = "{}";

    @Value("${com.blss.memberServices.provider.posServiceURL}")
    private String accPosServiceURL;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AccTokenUtility accTokenUtility;

    @Autowired
    private ResourceMessage resourceMessage;

    void setAccTokenUtility(AccTokenUtility accTokenUtility) {
        this.accTokenUtility = accTokenUtility;
    }

    void setResourceMessage(ResourceMessage resourceMessage) {
        this.resourceMessage = resourceMessage;
    }

    /**
     * @see MemberDetailsApiController#getMemberDetails(String, String)
     */
    @Override
    public MemberDetailsModel getMemberDetails(String storeId, String membershipIdentifier) {

        /**
         * Getting CAD token
         */
        String token = accTokenUtility.getCadToken();

        /**
         * Preparing the request
         */
        HttpHeaders headers = new HttpHeaders();

//        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        headers.set(CONTENT_TYPE_HEADER_NAME, MediaType.APPLICATION_JSON_VALUE);
        headers.set(AUTHORIZATION_HEADER_NAME, token);
        HttpEntity<String> entity = new HttpEntity<>(headers);

        /**
         * Creating the dispatch URL by means of userId and vehicleId
         */
        String dispatchURL = accPosServiceURL + "DispatchedEvent/{userId}/{vehicleId}";

        /**
         * Creating the URL variables and being valued by corresponding method parameters
         */
        Map<String, String> parameters = new HashMap<>();
//        parameters.put(USERID_PARAMETER_NAME, storeId);
        parameters.put(USERID_PARAMETER_NAME, "mr2");
//        parameters.put(VEHICLEID_PARAMETER_NAME, membershipIdentifier);
        parameters.put(VEHICLEID_PARAMETER_NAME, "VEH1");

        /**
         * Calling the rest webservice and returning response with body of type {@link AccMemberDetails}
         */
        ResponseEntity<String> response;
        MemberDetailsModel memberDetailsModel = null;
        AccMemberDetails accMemberDetails;
        try {
            response = restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);
            if (response == null || StringUtils.isBlank(response.getBody()) || EMPTY_RESPONSE.equals(response.getBody())) {
                throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier));
            } else {
                accMemberDetails = deserialize(response.getBody(), AccMemberDetails.class);
                String accErrorMessage = accMemberDetails.getUserMessage();
                if (!StringUtils.isBlank(accErrorMessage)) {
                    throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MESSAGE_FROM_API, "ACC", accErrorMessage));
                }
                memberDetailsModel = convert(accMemberDetails);
            }
        } catch (RestClientException e) {
            handleExceptions(e, storeId, membershipIdentifier);
        }
        return memberDetailsModel;
    }

    /**
     * This method is responsible for deserializing string REST response into an object of type {@link AccMemberDetails}
     */
    <T> T deserialize(final String response, final Class<T> responseClass) {
        try {
            return mapper.readValue(response, responseClass);
        } catch (IOException e) {
            throw new InternalServerException(resourceMessage.getMessage(MEMBER_ERROR_MAP_RESPONSE_OBJECT), e);
        }
    }

    /**
     * This method is responsible for converting an instance of type {@link AccMemberDetails} to an instance of type
     * {@link MemberDetailsModel}
     *
     * @param accMemberDetails an instance of type {@link AccMemberDetails}
     * @return an instance of type {@link MemberDetailsModel}
     */
    MemberDetailsModel convert(AccMemberDetails accMemberDetails) {
        MemberDetailsModel memberDetailsModel = new MemberDetailsModel();
        memberDetailsModel.setEventId(accMemberDetails.getEventId());
        memberDetailsModel.setMemberName(accMemberDetails.getMemberName());
        memberDetailsModel.setMembershipNumber(accMemberDetails.getMembershipNumber());
        memberDetailsModel.setMembershipLevel(accMemberDetails.getPricingLevel());
        return memberDetailsModel;
    }

    /**
     * This method is responsible for handling Exceptions may be thrown by ACC REST webservice
     *
     * @param e                    an instance of type {@link RestClientException}
     * @param storeId              an instance of type {@link String} and used in building exception messages
     * @param membershipIdentifier an instance of type {@link String} and used in building exception messages
     */
    private void handleExceptions(RestClientException e, String storeId, String membershipIdentifier) {
        if (e instanceof HttpStatusCodeException) {
            HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) e;
            HttpStatus httpStatusCode = httpStatusCodeException.getStatusCode();
            if (404 == httpStatusCode.value()) {
                throw new ResourceNotFoundException(resourceMessage.getMessage(MEMBER_ERROR_NOT_FOUND, storeId, membershipIdentifier), e);
            } else if (500 == httpStatusCode.value()) {
                throw new InternalServerException(resourceMessage.getMessage(MEMBER_SERVER_ERROR, "ACC"), e);
            } else {
                throw new InternalServerException(resourceMessage.getMessage(MEMBER_HTTP_STATUS_CODE_ERROR, "HttpStatusCodeException", "ACC"), e);
            }
        } else {
            throw new InternalServerException(resourceMessage.getMessage(MEMBER_REST_CLIENT_ERROR, "RestClientException", "ACC"), e);
        }
    }

问题

然而,在代码片段中调用"restTemplate.exchange(dispatchURL, HttpMethod.GET, entity, String.class, parameters);"后,我得到了UnhandledHttpStatusException。异常堆栈跟踪如下:

Caused by: org.springframework.web.client.UnknownHttpStatusCodeException: Unknown status code [443] null
    at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:60)
    at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:629)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:565)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:484)
    at com.blss.retailServices.memberServices.controllers.impl.acc.AccMemberDetailsApiControllerImpl.getMemberDetails(AccMemberDetailsApiControllerImpl.java:110)
  

如果有人能建议我解决方案,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

我使用&#34; -v&#34;用curl调用了这个web服务。以获得更多信息作为回应。结果,我从他们那边得到了同样的例外(443)。所以,听起来他们应该有一个更好的异常处理程序来返回有意义的异常消息。