Android中如何避免URL空值?Retrofit2请求含%00致服务端错误
Got it, let's tackle this issue head-on. The problem here is that your input text is sneaking in a null character (\0), which Retrofit encodes as %00 in the URL—and your server rejects this invalid value. Here are a few solid ways to fix it:
1. Clean the Input Before Sending (Simplest Approach)
The most straightforward fix is to strip out any null characters (or all control characters) from the keyword right when you get it from the EditText. This way, you never even send the problematic character to Retrofit.
// Get the raw input from EditText String rawKeyword = editText.getText().toString(); // Option 1: Target only null characters for removal String cleanedKeyword = rawKeyword.replace("\0", ""); // Option 2: Remove all invisible control characters (safer for unexpected edge cases) String cleanedKeyword = rawKeyword.replaceAll("\\p{Cntrl}", ""); // Pass the cleaned keyword to your API call apiService.getSkills(cleanedKeyword) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(/* your observer logic here */);
2. Add a Retrofit Interceptor to Clean Requests Globally
If you want to handle this for all API requests (not just the skills endpoint), adding an OkHttp Interceptor is a great way to enforce cleanup across your entire app. It’ll automatically strip %00 from any request URL before it’s sent to the server.
// Create the interceptor to clean null characters from URLs Interceptor nullCharCleanupInterceptor = chain -> { Request originalRequest = chain.request(); HttpUrl originalUrl = originalRequest.url(); // Replace any %00 occurrences in the full URL string String cleanedUrlString = originalUrl.toString().replace("%00", ""); HttpUrl cleanedUrl = HttpUrl.parse(cleanedUrlString); // Build and return the modified request Request cleanedRequest = originalRequest.newBuilder() .url(cleanedUrl) .build(); return chain.proceed(cleanedRequest); }; // Attach the interceptor to your OkHttpClient OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(nullCharCleanupInterceptor) .build(); // Initialize Retrofit with this client Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://www.example.com/api/v1/") .client(okHttpClient) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build();
3. Prevent Invalid Input at the Source (EditText Filter)
You can also add an InputFilter to your EditText to block users from entering control characters (including null) in the first place. This stops the problem before it even starts.
// Create a filter that rejects any control characters InputFilter controlCharFilter = (source, start, end, dest, dstart, dend) -> { for (int i = start; i < end; i++) { if (Character.isISOControl(source.charAt(i))) { // Return empty string to reject the invalid input return ""; } } // Return null to accept valid input return null; }; // Apply the filter to your EditText editText.setFilters(new InputFilter[]{controlCharFilter});
Quick Context on the Root Cause
Null characters (\0) can sneak into your EditText input from places like copy-pasted text (from sources with hidden control characters) or rare keyboard/input method bugs. Retrofit automatically URL-encodes all query parameters, turning \0 into %00—which most servers don’t accept as valid input.
内容的提问来源于stack exchange,提问作者Long Ranger

