preface

I don’t know, I haven’t been blogging for a few months, and I’ve lost that feeling. It takes 27 days to develop a good habit. It doesn’t take a cycle to give up a habit. Laziness does. Mainly, there is no good content to spread to the majority of gay friends, which also saves everyone’s reading time to brush tiktok HHHH, without saying to enter the theme

SAO operation directory

Also don’t nonsense, can see the following directory, which SAO operation, hope to help daily development of small partners.

  1. URL redirection
  2. Request body data is encrypted
  3. Dynamic adding of HEAD
  4. Request log capture

URL redirection

How to redirect, is to change a new URL, but the general server to do better, the client appears some chicken ribs. But it can also be used in everyday situations, such as scenarios, to test the switch to the generated environment. With more business, several people develop the background together, and everyone’s code does not agree with each other, which leads to different Baseurl. At this time, it is ok to modify through one entrance, otherwise, it will be very troublesome to modify every place, if the number of interfaces is large.

  • You can customize an Interceptor by creating a class that implements the Interceptor interface, and then add the Interceptor to the Okhttp initializer
public class TestInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        returnnull; }}Copy the code

Then add the interceptor where you need to initialize okHTTP

public class TestActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); OkHttpClient build = new OkHttpClient.Builder() .addInterceptor(new TestInterceptor()) .build(); }}Copy the code

So what do we need to do next? The interceptor is already written, and since it is defined as an interceptor, the request body information must be there. We can use the intercept method in the Interceptor interface to give us a parameter, Chain, where everything starts. Let’s see how we can do the SAO operation to change the original URL to achieve the redirection function


public class TestInterceptor implements Interceptor {
    private String newHost = "127.0.0.1"; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); / / http://127.0.0.1/test/upload/img? userName=xiaoming&userPassword=12345 String scheme = url.scheme(); // http https String host = url.host(); // 127.0.0.1 String path = url.encodedPath(); // /test/upload/img String query = url.encodedQuery(); // userName=xiaoming&userPassword=12345 StringBuffer sb = new StringBuffer(); String newUrl = sb.append(scheme).append(newHost).append(path).append("?").append(query).toString();

        Request.Builder builder = request.newBuilder()
                .url(newUrl);

        returnchain.proceed(builder.build()); }}Copy the code

You can change the baseUrl when you’re building a retrofit, but if you want to change the path of a retrofit, you’ll need to change it everywhere. In this case, you can use this as a unified entry and make a new path. Simple, for each of the following field description meaning I have a note in the back, you can see the split appearance

Request body data is encrypted

Since want to request body encryption, it must want to know where is the request body, and then you can encrypt, just the same really either encrypted url inside query content or encryption body body inside are all the same, as long as got the corresponding data we want to do what, some interface more wonderful work, he need a signature certification according to the content of the request body. So anyway, we’ve got the request body and of course we can do whatever we want, ok

  1. Encrypting query content
public class TestInterceptor implements Interceptor {
    private String newHost = "127.0.0.1"; @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); / / http://127.0.0.1/test/upload/img? userName=xiaoming&userPassword=12345 String scheme = url.scheme(); // http https String host = url.host(); // 127.0.0.1 String path = url.encodedPath(); // /test/upload/img String query = url.encodedQuery(); // userName=xiaoming&userPassword=12345 StringBuffer sb = new StringBuffer(); sb.append(scheme).append(newHost).append(path).append("?");
        Set<String> queryList = url.queryParameterNames();
        Iterator<String> iterator = queryList.iterator();
        
        for (int i = 0; i < queryList.size(); i++) {
            
            String queryName = iterator.next();
            sb.append(queryName).append("="); String queryKey = url.queryParameter(queryName); Sb. append(CommonUtils.getMD5(queryKey));if (iterator.hasNext()) {
                sb.append("&"); 
            }
        }


        String newUrl = sb.toString();

        Request.Builder builder = request.newBuilder()
                .url(newUrl);

        returnchain.proceed(builder.build()); }}Copy the code

This enables the concatenated Query content to be encrypted directly and uniformly. I’m just doing a simple MD5 encryption here and if the server and the client have defined a protocol for encryption and decryption, you can do a specific encryption here

  1. Encrypt the body contents

public class TestInterceptor implements Interceptor {
    private String newHost = "127.0.0.1";


    public static String requestBodyToString(RequestBody requestBody) throws IOException {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        returnbuffer.readUtf8(); } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); / / http://127.0.0.1/test/upload/img? userName=xiaoming&userPassword=12345 String scheme = url.scheme(); // http https String host = url.host(); // 127.0.0.1 String path = url.encodedPath(); // /test/upload/img String query = url.encodedQuery(); // userName=xiaoming&userPassword=12345 StringBuffer sb = new StringBuffer(); sb.append(scheme).append(newHost).append(path).append("?");
        Set<String> queryList = url.queryParameterNames();
        Iterator<String> iterator = queryList.iterator();

        for (int i = 0; i < queryList.size(); i++) {

            String queryName = iterator.next();
            sb.append(queryName).append("="); String queryKey = url.queryParameter(queryName); Sb. append(CommonUtils.getMD5(queryKey));if (iterator.hasNext()) {
                sb.append("&");
            }
        }


        String newUrl = sb.toString();


        RequestBody body = request.body();
        String bodyToString = requestBodyToString(body);
        TestBean testBean = GsonTools.changeGsonToBean(bodyToString, TestBean.class);
        String userPassword = testBean.getUserPassword(); // Encrypt the user password in the bodytestBean.setUserPassword(CommonUtils.getMD5(userPassword));
        
        String testGsonString = GsonTools.createGsonString(testBean);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), testGsonString);
        


        Request.Builder builder = request.newBuilder()
                .post(requestBody)
                .url(newUrl);

        returnchain.proceed(builder.build()); }}Copy the code

From the above, we can see that we first get the content of the body, then parse it, get the corresponding entity class, and then encrypt it, and then create a new body and post it to achieve the encryption of the body. This is just a body encryption method. It is also possible to take the body and encrypt it and then add the head to the encrypted thing as a signature.

Finally this interceptor – style encryption is also a way to unify the code entry.

Dynamic adding of HEAD

In everyday development, there may be more or less headers for each interface. It is not possible to say that every interface should write an interceptor to add headers. It’s time to think about this in a different way. How to do it? In fact, it is also to unify the code, the same operation should not be carried out in more than one place, so it is very troublesome to modify. Unified entrance, unified exit.


public class TestInterceptor implements Interceptor {
    private String newHost = "127.0.0.1";
    private String path1 = "/test/upload/img";
    private String path2 = "/test/upload/voice";

    public static String requestBodyToString(RequestBody requestBody) throws IOException {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        returnbuffer.readUtf8(); } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url(); / / http://127.0.0.1/test/upload/img? userName=xiaoming&userPassword=12345 String scheme = url.scheme(); // http https String host = url.host(); // 127.0.0.1 String path = url.encodedPath(); // /test/upload/img String query = url.encodedQuery(); // userName=xiaoming&userPassword=12345 StringBuffer sb = new StringBuffer(); sb.append(scheme).append(newHost).append(path).append("?");
        Set<String> queryList = url.queryParameterNames();
        Iterator<String> iterator = queryList.iterator();

        for (int i = 0; i < queryList.size(); i++) {

            String queryName = iterator.next();
            sb.append(queryName).append("="); String queryKey = url.queryParameter(queryName); Sb. append(CommonUtils.getMD5(queryKey));if (iterator.hasNext()) {
                sb.append("&");
            }
        }


        String newUrl = sb.toString();


        RequestBody body = request.body();
        String bodyToString = requestBodyToString(body);
        TestBean testBean = GsonTools.changeGsonToBean(bodyToString, TestBean.class);
        String userPassword = testBean.getUserPassword(); // Encrypt the user password in the bodytestBean.setUserPassword(CommonUtils.getMD5(userPassword));

        String testGsonString = GsonTools.createGsonString(testBean);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), testGsonString);
        
        Request.Builder builder = request.newBuilder()
                .post(requestBody)
                .url(newUrl);

        switch (path) {
            case path1:
                builder.addHeader("token"."token");
                break;
            case path2:
                builder.addHeader("token"."token");
                builder.addHeader("uid"."uid");
                break;
        }


    


        returnchain.proceed(builder.build()); }}Copy the code

I’m going to dynamically add headers depending on the path in the URL. Everyone realizes the way is different, as long as the way is right, how wanke is ok, see individual.

Request log capture

There are already log interceptors that you can use in everyday development, but let’s say we only want to see what we want and filter out what we don’t want. What to do. You have to define it yourself. Print out what you need. So as not to see too much every time mess. How to complete such a SAO operation through the interceptor. It was easy. We got everything we should have based on that.


public class TestInterceptor implements Interceptor {
    private String newHost = "127.0.0.1";
    private String path1 = "/test/upload/img";
    private String path2 = "/test/upload/voice";
    private String TAG = "TestInterceptor";
    public static String requestBodyToString(RequestBody requestBody) throws IOException {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        returnbuffer.readUtf8(); } @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); HttpUrl url = request.url(); / / http://127.0.0.1/test/upload/img? userName=xiaoming&userPassword=12345 String scheme = url.scheme(); // http https String host = url.host(); // 127.0.0.1 String path = url.encodedPath(); // /test/upload/img String query = url.encodedQuery(); // userName=xiaoming&userPassword=12345 RequestBody body = request.body(); String bodyToString = requestBodyToString(body); Log.e(TAG,scheme); Log.e(TAG,host); Log.e(TAG,path); Log.e(TAG,query);if (response != null) {
            ResponseBody responseBody = response.body();
            long contentLength = responseBody.contentLength();
            String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
            
            Log.e(TAG,response.code() + ' ' 
                    + response.message() + ' '
                    + response.request().url()+' '
                    + bodySize
                 );

            Headers headers = response.headers();
            for (int i = 0, count = headers.size(); i < count; i++) {
                Log.e(TAG,headers.name(i) + ":"+ headers.value(i)); }}returnchain.proceed(request); }}Copy the code

According to your own needs, I just simply print something. It’s also based on the code above.

ending

Spend an hour to write things, I hope to bring the old iron is the reserve of knowledge rather than a waste of time. It’s late. It’s late. It’s late.