当前位置: 首页 > 知识库问答 >
问题:

内容类型为application/x-www-form-urlencoded的HTTP Post请求在spring boot服务中不起作用

裴展
2023-03-14

我是一个新的spring boot最近,我试图做HTTP POST请求从一个android应用程序通过reverfit2 rest API库与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 boot应用程序代码示例

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);
    }

注:如果我从邮递员那里点击spring boot邮政服务,我会得到以下结果

但如果我从我的android客户endpoint击POST服务,它就会给我带来错误

“状态”:415,“错误”:“不支持的媒体类型”,“异常”:“org.springframework.web.httpmediatypenotsupportedexception”,“消息”:“内容类型'application/x-www-form-urlencoded;charset=utf-8'不支持”,“路径”:“/api/login”

共有2个答案

郎宏逸
2023-03-14

为了使spring正确加载表单编码数据,您需要将端点参数定义为:

public LoginData postLogin(@RequestBody MultiValueMap<String, String> body)

public LoginData postLogin(@RequestParam Map<String, String> body)
宓季同
2023-03-14

在使用application/x-www-form-urlencoded时,spring并不把它理解为RequestBody。因此,删除映射数据的参数列表中的@RequestBody注释,就像我在那里看到的那样。

请阅读这篇spring不懂应用程序/x-www-form-urlencoded

 类似资料:
  • 我正在使用OpenAPI生成器生成Spring REST API。下面是一个片段: 它生成一个Spring REST API方法(只是一个有趣的方法): 然后,我想使用从集成测试中调用它: 我得到一个错误: 我对服务器端进行了一点调试,看起来它需要一个多部分的内容,但我不明白为什么。 内容类型为application/x-www-form-urlencoded的Http Post请求在Spring

  • 问题内容: 是新来春目前正在试图做的HTTP POST请求的应用程序/ x-WWW的形式,URL编码,但是当我守这在我的头,然后春天不承认它,并说 了 有人知道如何解决吗?请评论我。 我的控制器的一个示例是: 问题答案: 问题在于,当我们使用application / x-www-form-urlencoded时,Spring不会将其理解为RequestBody。因此,如果要使用它,则必须删除@R

  • 我是spring的新手,目前正在尝试执行HTTP POST request Application/x-www-form-urlencoded,但当我将其保存在头中时,spring无法识别它,并对说 org.springframework.web.httpmediatypenotsupportedexception:不支持内容类型“application/x-www-form-urlencoded

  • 我有一个spring-boot应用程序,它唯一做的事情是接收http请求。 这是我的Spring管理员: 我在用邮递员寄请求。我的spring应用程序接收到的请求不能更改,因为代码不是由我的团队维护的。 请求标头 请求主体 我在这里发现了很多类似问题的问题,但不是我必须解决的完全相同的问题。我尝试添加和删除@RequestBody,将@RequestBody替换为@RequestParam,我尝试

  • 当内容类型为application/x-www-form-urlencoded;charset=UTF-8并且请求正文为text或application/json时,如何在控制器中进行post映射。我读到@RequestBody不能与UrlenCoded一起工作。如何重新发行这个问题。

  • 我激发下面的请求,它在一个项目中工作,但不是另一个项目。我试图禁用所有筛选器和参数解析器,但没有任何工作。 任何帮助或想法都将不胜感激。另外,如果有人能给我指出Spring解析参数的地方,我可以试着调试,看看会发生什么。