The problem

In XX system, a user needs to maintain too many projects and fill in too many tasks, resulting in a time saving. Only the first part of XX data is persisted to the database, while the data behind is not saved.

Figure 1

The screening process

1. Add logs and monitor parameter information

The first thought is whether the following part of the data in the process of saving abnormal. Check the logs and find that the fault does not exist.

Then add method parameter information log, data parameter information. Discover parameter set size=200, front-end send set size=400. Determine the problem can be caused by the server container environment (Nginx+Tomcat)

2. Development environment problems recur

2.1 Simulated data

Simulate online data in the test environment. As shown in figure 1

2.2 Configuring Only Tomcat

Start Tomcat directly in IDEA without nginx environment. If there is no problem, it can be temporarily determined as an Nginx problem.

However, new problems were discovered in the process.

org.springframework.beans.InvalidPropertyException: Invalid property 'detail[256]' of bean class [com.suning.asvp.mer.entity.InviteCooperationInfo]: Index of out of bounds in property path 'detail[256]'; nested exception is java.lang.IndexOutOfBoundsException: Index: 256, Size: 256 at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:833) ~ [spring beans - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:576) ~ [spring beans - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.beans.BeanWrapperImpl.getBeanWrapperForPropertyPath(BeanWrapperImpl.java:553) ~ [spring beans - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:914) ~ [spring beans - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76) ~ [spring beans - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:692) ~ [spring - the context - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at Org. Springframework. Validation. DataBinder. DoBind (DataBinder. Java: 588) ~ [spring - the context - 3.1.2. The jar: 3.1.2. RELEASE] at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:191) ~ [spring - web - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE] the at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:112) ~ [spring - web - 3.1.2. RELEASE. The jar: 3.1.2. RELEASE]Copy the code

View BeanWrapperImpl source code

else if(value instanceof List) { int index = Integer.parseInt(key); List list = (List) value; growCollectionIfNecessary(list, index, indexedPropertyName, pd, i + 1); value = list.get(index); // List = 256; index = 256;Copy the code
@SuppressWarnings("unchecked")  
    private void growCollectionIfNecessary(  
            Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {  
  
  
        if(! this.autoGrowNestedPaths) {return; } int size = collection.size(); // New elements are added to the list only when the number is less than the autoGrowCollectionLimitif (index >= size && index < this.autoGrowCollectionLimit) {  
            Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel);  
            if(elementType ! = null) {for(int i = collection.size(); i < index + 1; i++) { collection.add(newValue(elementType, name)); }}}}Copy the code

Find the definition of autoGrowCollectionLimit based on the above analysis

public class DataBinder implements PropertyEditorRegistry, TypeConverter {  
  
    /** Default object name used for binding: "target" */  
    public static final String DEFAULT_OBJECT_NAME = "target";  
  
    /** Default limit for array and collection growing: 256 */  
    public static final int DEFAULT_AUTO_GROW_COLLECTION_LIMIT = 256;  
  
    private int autoGrowCollectionLimit = DEFAULT_AUTO_GROW_COLLECTION_LIMIT; 
Copy the code

The solution is to add the following method to your Controller

@InitBinder  
protected void initBinder(WebDataBinder binder) {  
    binder.setAutoGrowNestedPaths(true);  
    binder.setAutoGrowCollectionLimit(1024);  
}  
Copy the code

The difference between this question and the online one is a bonus. The revolution has not yet succeeded, comrades still need to work !!!! = =

2.3 increase Nginx

After 2.2 struggles, temporarily determine whether the Nginx POST request parameters are limited. Configure the Nginx agent in the development environment

Nginx. Conf as follows

Upstream XXXXXXX {server 127.0.0.1:8080 weight=10 max_fails=2 fail_timeout=30s; } server { listen 80; server_name xxxxxxx.com; client_max_body_size 100M;# configure post size
    
    #charset koi8-r;
  
    #access_log logs/host.access.log main;
	
   location / {
		#proxy_next_upstream http_500 http_502 http_503 http_504 error timeout invalid_header;
		proxy_set_header        Host  $host;
		proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://xxxxxxx; expires 0; }}Copy the code

For client_max_body_size 100 m; The Internet is all about file uploads. But they upload data via post, request body, so it’s universal.

The test ~ ~

Functional, no recurrence of online problems. Cry to death ~ ~ ~

The revolution will continue

2.4 Tomcat Post Settings

Go to the online server and pull the configuration

<Connector port="1601" maxParameterCount="1000" protocol="HTTP / 1.1" redirectPort="8443" maxSpareThreads="750" maxThreads="1000" minSpareTHreads="50" acceptCount="1000" connectionTimeout="20000" URIEncoding="utf-8"/>
Copy the code

MaxParameterCount =”1000″ This parameter limits the number of parameters requested, thereby limiting the body size.

Configure this parameter in the development environment, test, and re-create the problem.

3. Solve

Once the cause of the problem is located, all that remains is how to solve it.

Two options:

  • Modifying Online Configurations

    This is difficult to implement, because the company uses a unified release and deployment platform, developers do not have access to the server.

  • Modify the code

    Modify the storage logic and fragment storage

conclusion

Problem detection, need to have a grasp of the overall, and then analyze the scope of impact. Can not be bogged down, the western medicine “headache cure head” way. It is possible that the final result is still to cure the head, but at this time the head is already built on the dialectics of Traditional Chinese medicine, the right medicine.