Some pit Spring Boot Record of small projects

A spring boot with existing back-office projects, project development front-end interface to interact with the rest, use Jython to call native python code. IDEA project-based development, deployment in the windows system.

The first pit: cross-domain requests

Front-end interfaces ajax request background, the background returns json data. Background independent testing (curl, restlet) no problem, given the front cross-domain problems arise.

First, we try to increase dataType ajax request and set jsonp, results not reported cross-domain problem, directly back into the error, the status code 200, some of the blog considered background data is not precise enough, not strictly json format, then not .

.ajax $ ({ // request method 
    of the type: "GET" ,
    contentType: "file application / JSON; charset = UTF-. 8", // the requested media type 
    URL: "http://127.0.0.1:8088/search?carId=" + carid, // request address 
    dataType: "jsonp" ,

    success: function (result) {
       ...

The final solution to the problem is to support cross-domain through the background, there's a small dip, cross-domain approach does not support the same in springboot1 and springboot2 in.

Under springboot2, we can increase cross-domain support through the following two steps.

1, write a configuration class, the added cross-domain mapping

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {

    public void addCorsMappings(CorsRegistry registry){
        registry.addMapping ( "/ **" )
                 // settings allow cross-domain requests domain of 
                .allowedOrigins ( "*" )
                 // if the certificate is no longer allowed to default on 
                .allowCredentials ( to true )
                 // settings allow methods 
                .allowedMethods ( " * " )
                 // cross-domain allows time 
                .maxAge (3600 );
    }
}

2, using the annotation configuration Controller

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/")
public class IndexController {
    private AlgorithmModel algorithmModel;
    private FileModel fileModel;

    @CrossOrigin(origins = "http://localhost:63342")
    @GetMapping(value = "/search")
    public Result search(@RequestParam String carId)
    {
        List<Route> routes = null;
        // check if file exists
        if(fileModel.fileExists(carId)){
            routes = fileModel.genRoutes(carId);
        }else{
            if(algorithmModel.call(carId) != null){
                routes = fileModel.genRoutes(carId);
            }else{
                return Result.fail("1");
            }
        }
        return Result.success("0", routes);
    }
}

PS: location annotation more flexible

  • You can directly annotate the class
  • Can be part of the class annotation, then the annotation on another portion of the method
  • Or direct annotation methods

The second pit: When packing PythonInterpreter run under the Jython error

Because to call external python code, I use Jython. PythonInterpreter to the bean, and incorporated into other bean.

@Bean
public PythonInterpreter getPythonInterpreter() {
    PythonInterpreter pyInterpreter = new PythonInterpreter();
    return pyInterpreter;
}

When running in the idea does not have any problem, being given as follows packaged runtime:

...
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-06-24 16:56:04.915 ERROR 51338 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexController' defined in URL [jar:file:/Users/zhengshuangxi/Desktop/car/vehicle-web-0.0.2-SNAPSHOT.jar!/BOOT-INF/classes!/cn/xidian/sxzheng/vehicleweb/controller/IndexController.class]: Unsatisfied dependency expressed through constructor parameter 0; 
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getAlgorithmModel' defined in class path resource [cn/xidian/sxzheng/vehicleweb/config/MyConfig.class]: Bean instantiation via factory method failed; 
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.xidian.sxzheng.vehicleweb.model.AlgorithmModel]: Factory method 'getAlgorithmModel' threw exception; 
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getPythonInterpreter' defined in class path resource [cn/xidian/sxzheng/vehicleweb/config/MyConfig.class]: Bean instantiation via factory method failed; 
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.python.util.PythonInterpreter]: Factory method 'getPythonInterpreter' threw exception; 
nested exception is ImportError: Cannot import site module and its dependencies: No module named site ...

According to information given can be learned getPythonInterpreter method error, the error message is "Can not import site module and its dependencies: No module named site", and here's why there is no site module, the solution is to modify the method getPythonInterpreter

@Bean   
public PythonInterpreter getPythonInterpreter() {
    Properties props = new Properties();
    props.put("python.home", "../jython-2.7.0");
    props.put("python.console.encoding", "UTF-8");
    props.put("python.security.respectJavaAccessibility", "false");
    props.put("python.import.site", "false");
    Properties preprops = System.getProperties();
    PythonInterpreter.initialize(preprops, props, new String[0]);
    PythonInterpreter pyInterpreter = new PythonInterpreter();
    return pyInterpreter;
}

 After modifying code handling, the problem is not the site, but later error "os module to find not see." These problems are mainly due to the use Jython run in java python program when its need to manually set the search path. And Jython has a fatal weakness, is that it supports the library too small, as some scientific computing library numpy so much trouble, so I later switch to execute python file Runtime, and I strongly recommend you use Runtime to execute an external program, io stream and collect the results.

    public String call(String carId){
        Process process;
        String command = "python3 " + pythonFilePath + " " + carId;
        System.out.println(command);
        String result = "";
        try{
            process = Runtime.getRuntime().exec(command);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while((line = in.readLine()) != null){
                result = result.concat(line);
            }
            in.close();
            process.waitFor();
        }catch(IOException e){
            e.printStackTrace ();
        }catch (InterruptedException e){
            e.printStackTrace ();
        }
        return result;
    }

 

The third pit: read external properties file

Because of the need packaged to run on other machines, so the python program set up on the location of the background after development is completed, some external parameter settings must be done through an external configuration file, which is written in the project application.properties can not be modified, it must to achieve external properties can be read configuration files. After each modify the properties file to restart the program can take effect.

Like application.properties file final figure is packaged in a jar, it can not be modified. We need a similar situation the right, at any time modify the configuration file in the config, and then can make changes to take effect by re-running the jar file.

 

Development phase, we can use an external configuration files @PropertySource notes, take notes and parameters in the configuration file by @Value.

After the deployment package, we can create directly in the current directory jar of config folder, and create a new file application.properties priority external file is greater than the internal configuration files, so we can manually modify configuration parameters application.properties be achieved in a production environment the modifications.

Guess you like

Origin www.cnblogs.com/zhengshuangxi/p/11079420.html