'Exception while reading request', 'detail': 'Cannot decode: java.io.StringReader@1aac9ea'}, 'status': 'failure'}

元气小坏坏 提交于 2021-01-29 11:12:12

问题


My first question is, what does "cannot decode: java.io.stringreader" mean?

My second question is, why do some strings work and others do not? I'm guessing that there's an issue with python passing certain strings with d0rked encoding?

My third question is, am I converting the XML values correctly before passing them to the REST body?

I'm taking XML files from a directory, parsing the XML, then populating a REST post to a ServiceNow instance. Essentially I'm bringing a TON of legacy tickets from one system to another. I've solved the issues where special characters appear (like bullets). But for some reason, I keep getting the Cannot decode: java.io.stringreader@bleh error on some of the XML records, and not others. I've tried manually changing the text in that element (request) to just one word, that didn't work. So that leads me to believe that it has something to do with the encoding. In my response, I'm seeing that it was all sent in utf-8 as designed. I just don't understand what the issue is. And it's only with the request element. Everything else works perfectly.

I've tried countless ways of changing the parsed XML to strings, text, encoding and decoding it. It's just strange that all the other XML elements that are converted to .text work flawlessly. It's just the request element.

def restMessage(number, subject, queue, opendate, closedate, request, history, final, category, subcategory):
# Set the request parameters
    import requests
    url = 'https://*.service-now.com/api/now/import/sn_hr_core_mayo_case_import'

    # Eg. User name="admin", Password="admin" for this code sample.
    user = '*'
    pwd = '*'

    # Set proper headers
    headers = {"Content-Type":"application/json","Accept":"application/json"}

    # Build body
    body = "{\"u_state\":\"3\",\"u_opened_at\":\""+opendate+"\",\"u_closed_at\":\""+closedate+"\",\"u_source\":\"Self Service\",\"u_hr_service\":\"e2e4665cdb4f77003693f8fdbf96198b\",\"u_topic_category\":\"cec4bc2d9f931200d9011977677fcfe8\",\"u_opened_for\":\""+subject+"\",\"u_subject_person\":\""+subject+"\",\"u_assigned_to\":\"system\",\"u_queue\":\""+queue+"\",\"u_assignment_group\":\"f65370019f22120047a2d126c42e705c\",\"u_correlation_id\":\""+number+"\",\"u_request\":\""+request+"\",\"u_archive_category\":\""+category+"\",\"u_archive_subcategory\":\""+subcategory+"\"}"

    # Do the HTTP request
    response = requests.post(url, auth=(user, pwd), headers=headers ,data=body)

    # Check for HTTP codes other than 200
    #if response.status_code != 200:
    print('Status:', response.status_code, 'Headers:', response.headers, 'Error Response:', response.json())
    # Toggle exit if you want to only do one record.
    # exit()
    # Decode the JSON response into a dictionary and use the data
    data = response.json()
    print("Data from response = " + str(data))

#---------parse XML files from directory-----------
import os
from xml.etree import ElementTree as ET

# files are in a sub folder where this script is being ran
path = "attachments"
total = 0
count = 0

# Get the total number of xml records
files = os.listdir(path)
for x in files:
    if x.endswith(".xml"):
        total += 1

for filename in os.listdir(path):
    # Only get xml files
    if filename.endswith(".xml"):
        fullname = os.path.join(path, filename)
    # This joins full path / filename to trigger parser
        tree = ET.parse(fullname)
        # print(etree.tostring(root, pretty_print=True))
        # from xml.dom.minidom import parse
        # dom = parse(fullname)
        # print('<?xml version="{}" encoding="{}"?>'.format(dom.version, dom.encoding))

        # Parse the files..
        # Build tags from all the child elements in root IE: /CASE
        print("tree Obj ID= " + str(tree))
        qnumber = tree.find("NUMBER")
        qstatus = tree.find("STATUS")
        qqueue = tree.find("QUEUE")
        qcategory = tree.find("CATEGORY")
        qsubcategory = tree.find("SUB_CATEGORY")
        qsubject = tree.find("USER_ID")
        qopendate = tree.find("OPEN_DATE")
        qclosedate = tree.find("CLOSE_DATE")
        qrequest = tree.find("REQUEST")
        qhistory = tree.find("HISTORY_RESPONSE")
        qfinal = tree.find("FINAL_RESPONSE")

        #Convert everything to strings
        number = qnumber.text
        status = qstatus.text
        category = qcategory.text
        subcategory = qsubcategory.text
        queue = qqueue.text
        subject = qsubject.text
        opendate = qopendate.text
        closedate = qclosedate.text
        request = qrequest.text
        history = qhistory.text
        final = qfinal.text

        # Convert Special Characters
        # bad_chars = ['•','/']
        # for i in bad_chars:
        #     request = request.replace(i, '-')
        # # request =  ''.join([i for i in p_request if i.isdigit()])
        # request.encode(encoding='UTF-8')

        print(request)

        #Print case number to assist with knowing where in count
        print("Case Number: " + number)
        count += 1
        print("Count: " + str(count))
        print("Total: " + str(total))
        restMessage(number, subject, queue, opendate, closedate, request, history, final, category, subcategory)

This is the response I'm getting on certain records:

Status: 400 Headers: {'error': {'message': 'Exception while reading request', 'detail': 'Cannot decode: java.io.StringReader@1aac9ea'}, 'status': 'failure'}

With the ones that work (for no apparent reason):

Status: 201 Headers: {'import_set': 'ISET0010005', 'staging_table': 'sn_hr_core_*_case_import', 'result': [{'transform_map': '* Case Import', 'table': 'sn_hr_core_case', 'display_name': 'number', 'display_value': 'HRC0001165', 'record_link': 'https://*.service-now.com/api/now/table/sn_hr_core_case/a3669014db8777003693f8fdbf9619b4', 'status': 'ignored', 'sys_id': 'a3669014db8777003693f8fdbf9619b4', 'status_message': 'No field values changed'}]}

I have removed some sensitive information for obvious reasons. You will see a * in that case.

Here is the XML:

<?xml version="1.0" encoding="UTF-8"?>
<CASE>
  <NUMBER>20514217</NUMBER>
  <PARENT>
  </PARENT>
  <STATUS>1-CLOSED</STATUS>
  <OPEN_DATE>12/01/2017 00:29:46</OPEN_DATE>
  <CLOSE_DATE>12/05/2017 17:42:26</CLOSE_DATE>
  <SOURCE>Self Service</SOURCE>
  <PROCESS>HR INTERNAL REQUEST FORM</PROCESS>
  <CATEGORY>HR Connect</CATEGORY>
  <SUB_CATEGORY>Personnel Action Change/Update</SUB_CATEGORY>
  <USER_ID>210140</USER_ID>
  <LAST_NAME>Mickey mouse</LAST_NAME>
  <FIRST_NAME>Mickey mouse</FIRST_NAME>
  <SITUATION>SELECT...</SITUATION>
  <PRIORITY>5 Days</PRIORITY>
  <ADVISOR_NAME>Donald Duck</ADVISOR_NAME>
  <TEAM>2 HR SRV CNTR PA</TEAM>
  <NEXT_ACTION>
  </NEXT_ACTION>
  <PROCESS_STATUS>Verified</PROCESS_STATUS>
  <TRANSFERT_DATE>
  </TRANSFERT_DATE>
  <DEADLINE>12/12/2017 17:07:12</DEADLINE>
  <QUEUE>HR Internal Request</QUEUE>
  <FROZEN_DATE>
  </FROZEN_DATE>
  <OTHER_EMPLOYEE_ID>210140</OTHER_EMPLOYEE_ID>
  <REQUEST>Please complete a multi-add to this employee's record for the 11-29-2017 pay period. See attached request form with all pertinent PA details.

Thank you,
Donald Duck</REQUEST>
  <HISTORY_RESPONSE>[2017-12-01 17:52:09 - Donald Duck] Thank you for contacting HR Connect, your request for Mickey mouse has been processed.

[2017-12-01 17:52:10 - Donald Duck] Thank you for contacting HR Connect, your request for Melissa A. Gilbertson has been processed.</HISTORY_RESPONSE>
  <FINAL_RESPONSE>Thank you for contacting HR Connect, your request for Mickey mouse has been processed.</FINAL_RESPONSE>
</CASE>

--I've added a screenshot of what I think the problem is. Looks like the ServiceNow json parser doesn't like \n 's? (return carriages).. I will post more as I work towards the solution.


回答1:


This ended up being an issue with the encoding in the source xml records. Python couldn't translate a ton of weird junk characters. I created a way to strip out the odd characters. Here's the code I used...

def fix_multi_line_string(text):
    '''Given a string input,
    replace all unwanted characters with desginated replacements.
    Return the fixed string.'''
    char_map = {
        '•': '-',
        '\t': '',
        '\n': '',
        '\r': '',
        '\u200b': '',
        '"': "'",
        '\ufffd': '',
        '\uf0b7': '',
        '\uf0a7': '',
        '\uf071': '',
        '\u25e6': '',
        '\uf020': '',
        '\u2265': '',
        '\u200e': '',
        '\uf0d8': '',
        '\u2010': '',
        '\uf04a': '',
        '\u25fe': '',
        '\u2610': '',
        '\u2015': '',
        '\u2612': '',
        '\uf04c': '',
        '\uf15c': '',
        '\ue1ef': '',
        '\u25b2': '',
        '\U0001f609': '',
        '\u2502': '',
        '\uf02a': '',
        '\uf0e0': '',
        '\uf028': '',
        '\u25a1': '',
        '\ue0e8': '',
        '\u2003': '',
        '\uf0a0': '',
        '\ue900': '',
        '\ue901': '',
        '\ue076': '',
        '\ue1d9': '',
        '\ue1ed': '',
        '\u25bc': '',
        '\uf073': '',
        '\ue099': '',
        '\uf0fc': '',
        '\uf0df': '',
        '\uff08': '',
        '\u2002': '',
        '\uf0e8': '',
        '\uf07f': '',
        '\uf06f': '',
        '\u263a': '',
        '\ue1b4': '',
        '\ue1b4': '',
        '\u2500': '',
        '\uf084': '',
        '\ue0ca': '',
        '\U00100078': '',
        '\uf027': '',
        '\uf0ac': '',
        '\U0001f604': '',
        '\uff1f': '',
        '\uff0c': '',
        '\uff01': '',
        '\u2219': '',
        '\u2219': '',
        '\U0001f60a': '',
        '\uf0a8': '',
        '\ue172': '',
        '\ue080': '',
        '\ue113': '',
        '\ue1bc': '',
        '\ue202': '',
        '\u2190': '',
        '\u2192': '',
        '\uf076': '',
        '\ue021': '',
        '\uf06e': '',
        '\uf030': '',
        '\uf077': '',
        '\uf111': '',
        '\uf12a': '',
        '\ue22a': '',
        '\u2981': '',
        '\uf02d': '',
        '\uf037': '',
        '///': ''
    }
    for char in char_map:
        text = text.replace(char, char_map[char])

    return text


来源:https://stackoverflow.com/questions/57289682/exception-while-reading-request-detail-cannot-decode-java-io-stringreade

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!