Konnte nicht schreiben, Anfrage: Nein geeignet HttpMessageConverter gefunden für Anfrage Typ [org.json.JSONObject] und content-type [application/json]
Ich bin Graben mich bei dem Versuch zu senden eine POST-Anforderung mit einer JSON-Nutzlast an einen remote-server.
Diese ERHALTEN curl-Befehl funktioniert:
curl -H "Accept:application/json" --user aaa@aaa.com:aaa "http://www.aaa.com:8080/aaa-project-rest/api/users/1" -i
Und dieser POST arbeitet auch fein:
curl -H "Accept:application/json" -H "Content-Type: application/json" "http://www.aaa.com:8080/aaa-project-rest/api/users/login" -X POST -d "{ \"email\" : \"[email protected]\", \"password\" : \"aaa\" }" -i
Und so werde ich versuchen, ihn zu imitieren, in meine Android-app.
Die app funktioniert gut auf die erste GET-Anfrage, aber gibt 400 Bad Request am zweiten PFOSTEN ein.
Hier ist der code für die GET-Anforderung:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders httpHeaders = Common.createAuthenticationHeaders("[email protected]" + ":" + "aaa");
User user = null;
ResponseEntity<User> responseEntity = restTemplate.exchange("http://" + REST_HOST + ":8080/aaa-project-rest/api/users/" + 1L, HttpMethod.GET, new HttpEntity<Object>(httpHeaders), User.class);
Hier ist der Quellcode für die POST-Anforderung:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
User user = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
JSONObject jsonCredentials = new JSONObject();
jsonCredentials.put("email", REST_LOGIN);
jsonCredentials.put("password", REST_PASSWORD);
ResponseEntity<User> responseEntity = restTemplate.exchange("http://" + REST_HOST + ":" + REST_PORT + "/" + REST_APP + "/api/users/login",
HttpMethod.POST, new HttpEntity<Object>(jsonCredentials, httpHeaders), User.class);
Aber es gibt die Meldung:
Could not write request: no suitable HttpMessageConverter found for request type [org.json.JSONObject] and content type [application/json]
Hier ist die Spring-REST-controller:
@RequestMapping(value = RESTConstants.SLASH + RESTConstants.LOGIN, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<UserResource> login(@Valid @RequestBody CredentialsResource credentialsResource, UriComponentsBuilder builder) {
HttpHeaders responseHeaders = new HttpHeaders();
User user = credentialsService.checkPassword(credentialsResource);
userService.clearReadablePassword(user);
if (user == null) {
return new ResponseEntity<UserResource>(responseHeaders, HttpStatus.NOT_FOUND);
} else {
tokenAuthenticationService.addTokenToResponseHeader(responseHeaders, credentialsResource.getEmail());
responseHeaders.setLocation(builder.path(RESTConstants.SLASH + RESTConstants.USERS + RESTConstants.SLASH + "{id}").buildAndExpand(user.getId()).toUri());
UserResource createdUserResource = userResourceAssembler.toResource(user);
ResponseEntity<UserResource> responseEntity = new ResponseEntity<UserResource>(createdUserResource, responseHeaders, HttpStatus.CREATED);
return responseEntity;
}
}
@RequestMapping(value = RESTConstants.SLASH + "{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<UserResource> findById(@PathVariable Long id, UriComponentsBuilder builder) {
HttpHeaders responseHeaders = new HttpHeaders();
User user = userService.findById(id);
if (user == null) {
return new ResponseEntity<UserResource>(responseHeaders, HttpStatus.NOT_FOUND);
} else {
UserResource userResource = userResourceAssembler.toResource(user);
responseHeaders.setLocation(builder.path(RESTConstants.SLASH + RESTConstants.USERS + RESTConstants.SLASH + "{id}").buildAndExpand(user.getId()).toUri());
ResponseEntity<UserResource> responseEntity = new ResponseEntity<UserResource>(userResource, responseHeaders, HttpStatus.OK);
return responseEntity;
}
}
Den CredentialsResource class code:
public class CredentialsResource extends ResourceSupport {
@NotEmpty
@Email
private String email;
@NotEmpty
private String password;
public CredentialsResource() {
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- Können Sie zeigen die definition der REST-Controller auf dem server?
- Ich habe den controller. Auch ich merke nun, die Antwort ist ein 401 Unauthorized
- Die curl-Anfrage Benutzer/1, aber android ist der Benutzer/login
- Für die unbefugte Teil, sind Sie nicht senden Sie die Benutzername/Passwort auf die überschriften
- Spot auf. Ich habe gerade auch gemerkt. Ich habe die Beispiel-curl-Anfrage zu entsprechen, um die Anwendung Anforderung.
- Sie sehen, nichts falsch in der Weise, wie ich versuchen, vorbei an den header ?
- Sorry Jungs. Es war ein Tippfehler, die ich eingeführt in die Anwendung anfordern, die Auslöser für die 401. Jetzt ist es korrigiert die Antwort ist eine schöne 200.
- Ich war Durcheinander, meine Frage mit zwei unterschiedlichen Anforderungen. Ich räumte das ganze testen und es hoffentlich jetzt Sinn macht auf den neuen reader.
- Was ich undestand Ihrer Anfragen ist, dass der /die Benutzer/1 funktioniert mit basic-Authentifizierung, die aber /users/login nicht (Du bist nicht übergabe von Anmeldeinformationen in der gleichen Weise). Ist es richtig?
- Genau. Die login-url-Anfrage geht ein json-Objekt mit den Anmeldeinformationen, und nicht in den Kopf. Die demo-curl zeigt mit diesem zu arbeiten.
- Können Sie nach CredentialsResource Klasse code?
- Ich habe das CredentialsResource Klasse code.
- Ich Frage mich, warum die app-Anforderung macht die server-look-up für eine single-string-Konstruktor, wenn das Beispiel curl man nicht.
- Auf den ersten, das war ein REST, Angular-app und ich bin versucht, indem ein Android-client, um es. Ich habe zuerst eine login-Anfrage und der server erstellt einen JWT-JSON Web Token, die verwendet wird, in der die nachfolgenden Anforderungen. Meint Ihr, ich könnte diese verschieben: tokenAuthenticationService.addTokenToResponseHeader(responseHeaders, credentialsResource.getEmail()); aus der login-controller in der security-filter ? Dann würde ich nicht auf die login-controller nicht mehr.. ich Frage mich was am besten ist, wenn dabei ein JWT, wenn es ist, verwenden Sie den login-controller oder einen Sicherheitsfilter. Ist es gutes design zu mischen, Basic-auth mit JWT ?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Recht spät zu Antworten, aber ich habe gerade hitten das gleiche problem und nahm mir einige Zeit, um es zu lösen. Also, ich denke, ich würde besser teilen und verfolgen meine Lösung.
Eigentlich die Ausnahme, die ausgelöst wird, völlig irreführend. Stellte sich heraus, das problem ist nicht, dass die
MappingJackson2HttpMessageConverter
wusste nicht, wie marshall mein Objekt -so seltsam Klang, als JSON-, sondern eine Konfiguration der zugrunde liegendenObjectMapper
.Was ich getan habe ist zu deaktivieren die Eigenschaft
SerializationFeature.FAIL_ON_EMPTY_BEANS
wieund angefangen hat alles wie erwartet funktioniert.
Ich musste ein paar Dinge tun, damit es funktioniert.
Als erstes musste ich die konvertieren das JSONObject zu einem string, wie in:
Der Grund dafür ist, dass es keine mapping-Nachricht-Konverter für die JSONObject Klasse, während es gibt auch eine für die String-Klasse.
Sekunde, die ich zu bestehen hatte einen true-Wert für das RestTemplate Konstruktor. Geschieht dies nicht, würde ich eine 400 Bad Request.
Den wahren Wert sagt den rest Vorlage für die Verwendung der Standard-Konvertern. Wenn jemand weiß, warum dies so ist, würde ich gerne mehr darüber wissen.
Dritten habe ich entfernt nicht benötigte Jackson-Konverter:
Diese Dinge getan, die Anfrage läuft einwandfrei.
Hier ist der vollständige code:
Ich vermute, es könnte ein Weg sein, um ausdrücklich einen Jackson-Konverter und überspringen Sie den wahren Wert in der übrigen template-Konstruktor, aber das ist nur eine Vermutung.
Ausnahme "keine passenden HTTPMessageConverter gefunden" ausgegeben, wenn nicht die JSON-Implementierung ist in die Klasse Pfad. Haben Sie einen Blick auf RestTemplate source code:
Fügen Sie ein JSON-Implementierung, die Klasse path. E. g.:
Ich weiß... zu spät. Aber hier bin ich.
Ich behoben, das senden von Java-Objekt, anstatt ein JSONObject, so etwas wie dieses:
Wo JsonUtils.stringToObject ist meine eigene konvertieren-Dienstprogramm.
Spring RestTemplate nicht wissen, wie Sie zu serialisieren, die das Android-org.json.JSONObject Klasse. (org.json.JSONObject ist nicht verfügbar in der "normalen" - /desktop-Java)
RestTemplate für Android unterstützt
Jackson JSON Processor, Jackson 2.x und Google Gson.
pro: https://docs.spring.io/autorepo/docs/spring-android/1.0.1.RELEASE/reference/html/rest-template.html
Mit Jackson auf dem classpath RestTemplate sollten verstehen, wie zum serialisieren von Java-beans.
P. S. Es wäre ziemlich einfach, schreiben Sie Ihre eigenen JSONObjectHttpMessageConverter wenn Sie wollten weiterhin mit JSONObject, Ihr Konverter sollte nur noch zu nennen .toString()