我最近刚开始使用Spring Boot,我正在尝试通过Retrofit2 Rest API库从一个Android应用程序发出HTTP POST请求,并使用application / x-www-form-url编码,但是当我点击spring boot POST服务时,它向我显示错误以下
“状态”:415,“错误”:“不受支持的媒体 类型“,”异常“:” org.springframework.web.HttpMediaTypeNotSupportedException“,”消息“:”内容 类型'application / x-www-form-urlencoded; charset = UTF-8'不是 支持”,“路径”:“ / api / login”
有人知道如何解决吗?
这是我的代码Android代码示例
ApiService.java
public interface ApiService {
@FormUrlEncoded
@POST("/api/login")
Call<LoginData> postLogIn(
@Field("username") String username,
@Field("password") String password);
}
ApiHandler.java
private static final String SERVER_URL = "http://192.168.0.12:8080/";
private static final long CONNECTION_TIMEOUT = 30;
public static Retrofit restAdapter;
//public static final int CONNECTION_TIME_OUT = 120;
private static Retrofit getRestAdapter() {
if (restAdapter == null) {
restAdapter = new Retrofit.Builder()
.baseUrl(SERVER_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(getClient()).build();
}
return restAdapter;
}
private static OkHttpClient getClient() {
OkHttpClient.Builder okClientBuilder = new OkHttpClient.Builder();
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okClientBuilder.addInterceptor(httpLoggingInterceptor);
okClientBuilder.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okClientBuilder.readTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okClientBuilder.writeTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS);
return okClientBuilder.build();
}
PostHandler.java
@Override
public void callAPI(final Context context, final ApiClientResponse callback, Object arg0) {
this.callback = callback;
apiService.postLogIn(Login.username, Login.password).enqueue(new Callback<LoginData>() {
@Override
public void onResponse(Call<LoginData> call, Response<LoginData> response) {
if (response.isSuccessful()) {
LoginData loginData = response.body();
successLoginData = loginData;
successCallBack();
} else {
ApiErrorHandler.handleError(context, response, errorResponse);
}
}
@Override
public void onFailure(Call<LoginData> call, Throwable t) {
ApiErrorHandler.handleError(context, t, errorResponse);
}
RetrofitErrorResponse errorResponse = new RetrofitErrorResponse() {
@Override
public void errorMessage(String errorMessage) {
failureCallBack(errorMessage);
}
@Override
public void tSyncError() {
}
@Override
public void invalidTokenError() {
}
};
});
}
LoginData.java模型类
@Generated("org.jsonschema2pojo")
public class LoginData {
@SerializedName("access_token")
@Expose
private String accessToken;
@SerializedName("token_type")
@Expose
private String tokenType;
@SerializedName("refresh_token")
@Expose
private String refreshToken;
@SerializedName("expires_in")
@Expose
private long expiresIn;
@SerializedName("scope")
@Expose
private String scope;
// getter setter
}
这是我的Spring引导应用程序代码示例
MainApplicationClass.java
@SpringBootApplication
public class MainApplicationClass {
public static void main(String[] args) {
SpringApplication.run(MainApplicationClass.class, args);
}
}
Controller.java
@RestController
public class BlogController {
@Autowired
BlogRespository blogRespository;
BlogMockedData blogMockedData = BlogMockedData.getInstance();
@GetMapping("/blog")
public List<Blog> index() {
return blogMockedData.fetchBlogList();
}
@GetMapping("/blog/{id}")
public Blog show(@PathVariable String id) {
int blogId = Integer.parseInt(id);
return blogMockedData.getBlogById(blogId);
}
@PostMapping(value = "/api/login",
consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE},
produces = {MediaType.APPLICATION_JSON_UTF8_VALUE, MediaType.APPLICATION_JSON_VALUE}
)
public LoginData postLogin(@RequestBody Map<String, String> body) {
String userName = body.get("username");
String password = body.get("password");
return blogMockedData.getLoginToken(userName, password);
}
注意::如果我从POSTMAN中启动了spring boot POST服务,我将得到低于结果
但是,如果我从Android客户端访问POST服务,则会收到错误消息
“状态”:415,“错误”:“不受支持的媒体 类型“,”异常“:” org.springframework.web.HttpMediaTypeNotSupportedException“,”消息“:”内容 类型'application / x-www-form-urlencoded; charset = UTF-8'不是 支持”,“路径”:“ / api / login”
答案 0 :(得分:0)
要使Spring正确加载表单编码数据,您需要将端点参数定义为:
public LoginData postLogin(@RequestBody MultiValueMap<String, String> body)
或
public LoginData postLogin(@RequestParam Map<String, String> body)
答案 1 :(得分:0)
使用application / x-www-form-urlencoded时,Spring不能将其理解为RequestBody。因此,在映射数据的参数列表中删除@RequestBody批注,因为我在那里可以看到它。
请阅读此Spring doesn't understand application/x-www-form-urlencoded
答案 2 :(得分:0)
在 Spring Boot 中处理 URL 编码的 POST ( Content-Type: application/x-www-form-urlencoded )
这不起作用:
public String processForm(@RequestBody RespFormDTO formDTO,
HttpServletRequest request, HttpServletResponse response) {
这会起作用:
public String processForm(RespFormDTO formDTO,
HttpServletRequest request, HttpServletResponse response) {