One ,vue Project development plan

use vue Official scaffolding to create a separate front end project , Be completely independent of the backend development and deployment , Deploy a pure backend separately restful Services for , And the front end directly adopts nginx To deploy , This is called the complete front-end and back-end separation architecture development mode , But there's a lot in separation api The problem of authority needs to be solved , Including deployed vue
router Routing needs to be on nginx Medium configuration rewrite rule . This completely separate front and back architecture is also adopted by Internet companies , Back end servers no longer need to handle static resources , It can also reduce some pressure on back-end servers .

Two , Why do the front and back ends separate and develop and merge

In traditional industries, many are dominated by project ideas , Not the product , A project will be sold to many customers , And deploy it to the client's local computer room . In some traditional industries , The technology of deployment and implementation personnel cannot be compared with the operation and maintenance team of Internet company , Because of various uncertain environments, it can not be built automatically , Containerization deployment, etc . Therefore, in this case, the service software requirements at deployment time are minimized , And try to keep the number of bags out as small as possible . In view of this situation, the independent development of front and back end is adopted in the development , The whole development mode and the above mentioned vue The project development plan is the same , But on the back end springboot Package and release the build output of the front end together , Finally, just deploy springboot The project of , No more installation required nginx The server .

Three ,springboot and vue Key operations for consolidation

In fact, the development of this kind of separation of front and back ends in this paper , After the front end is developed, it will build Built dist lower static Files in and index.html Copy directly to springboot Of resource/static lower , Here is an example :

vue Front end projects :

springboot project :

 

 

This is the simplest way to merge , But if it is developed as an engineering level project , Manual merging is not recommended , It is also not recommended to commit the front-end code to springboot Of resouce lower , A good way to do this is to keep the front and back ends completely independent of each other , Project code does not affect each other , With the help of jenkins Such a build tool is building springboot Trigger the front-end build and write automation scripts to webpack Copy the constructed resources to springboot Next step jar Packaging of , At last, we get a fully inclusive springboot Project .

Three , Core issues of integration

There will be two big problems after the above integration :

1. Unable to properly access static resources .

2. vue router The path of the route cannot be resolved normally .

Solve the first problem , We have to reassign springboot Static resource processing prefix for , code :
@Configuration public class SpringWebMvcConfig extends WebMvcConfigurerAdapter
{ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry); } }

The way to solve the second problem is to vue The routing path of rewrite, hand router To deal with , instead of springboot Handle by yourself ,rewrite When routing paths are uniformly added, the most , And then springboot Filter and intercept specific suffixes to forward requests to vue Routing of . as :
const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ {
path: '/ui/first.vhtml', component: First }, { path: '/ui/second.vhtml',
component: secondcomponent } ] })
The backend intercepts the vhtml All of them router To deal with , This method is feasible after the backend write filter intercepts , But the direct access path with suffix of front-end development will have problems .

Another way is to route to the front end path Add a uniform prefix, such as /ui, In this case, the backend write filter matches the prefix , It will not affect the route resolution problem of the front-end development alone . Filter references are as follows :
/** * be used to rewrite vue router * * @author yu on 2017-11-22 19:47:23. */
public class RewriteFilter implements Filter { /** * need rewrite Destination address to */ public
static final String REWRITE_TO = "rewriteUrl"; /** * Intercepted url,url Wildcards are separated by semicolons */
public static final String REWRITE_PATTERNS = "urlPatterns"; private
Set<String> urlPatterns = null;// to configure url wildcard private String rewriteTo = null;
@Override public void init(FilterConfig cfg) throws ServletException {
// Initialize interception configuration rewriteTo = cfg.getInitParameter(REWRITE_TO); String exceptUrlString
= cfg.getInitParameter(REWRITE_PATTERNS); if
(StringUtil.isNotEmpty(exceptUrlString)) { urlPatterns =
Collections.unmodifiableSet( new
HashSet<>(Arrays.asList(exceptUrlString.split(";", 0)))); } else { urlPatterns
= Collections.emptySet(); } } @Override public void doFilter(ServletRequest
req, ServletResponse resp, FilterChain chain) throws IOException,
ServletException { HttpServletRequest request = (HttpServletRequest) req;
String servletPath = request.getServletPath(); String context =
request.getContextPath(); // Matching path override if (isMatches(urlPatterns, servletPath)) {
req.getRequestDispatcher(context+"/"+rewriteTo).forward(req, resp); }else{
chain.doFilter(req, resp); } } @Override public void destroy() { } /** *
Match return true, Mismatch return false * @param patterns Regular expression or wildcard * @param url Requested url * @return
*/ private boolean isMatches(Set<String> patterns, String url) { if(null ==
patterns){ return false; } for (String str : patterns) { if
(str.endsWith("/*")) { String name = str.substring(0, str.length() - 2); if
(url.contains(name)) { return true; } } else { Pattern pattern =
Pattern.compile(str); if (pattern.matcher(url).matches()) { return true; } } }
return false; } }
Registration of filters :
@SpringBootApplication public class SpringBootMainApplication { public static
void main(String[] args) {
SpringApplication.run(SpringBootMainApplication.class, args); } @Bean public
EmbeddedServletContainerCustomizer containerCustomizer() { return (container ->
{ ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED,
"/errors/401.html"); ErrorPage error404Page = new
ErrorPage(HttpStatus.NOT_FOUND, "/errors/404.html"); ErrorPage error500Page =
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/errors/500.html");
container.addErrorPages(error401Page, error404Page, error500Page); }); } @Bean
public FilterRegistrationBean testFilterRegistration() { FilterRegistrationBean
registration = new FilterRegistrationBean(); registration.setFilter(new
RewriteFilter());// register rewrite filter registration.addUrlPatterns("/*");
registration.addInitParameter(RewriteFilter.REWRITE_TO,"/index.html");
registration.addInitParameter(RewriteFilter.REWRITE_PATTERNS, "/ui/*");
registration.setName("rewriteFilter"); registration.setOrder(1); return
registration; } }

At this time springboot The routing resources of the front end can be handed over to the routing agent . So far, the whole scheme of separating front and back development and merging is completed . In this way, it is easy to completely separate the front and back development deployment when conditions permit in the later stage .

Technology
©2019-2020 Toolsou All rights reserved,
Obviously post Why does the request display parameters in the address bar ?git Pull the remote branch and switch to it Vue Development tips c Language rose advertising code pytorch of ResNet18( Yes cifar10 The accuracy of data classification is achieved 94%)C Language confession practice small program ( Suitable for beginners )ajax get Request Chinese parameter garbled solution use mt-range The effect of changing a number with the sliding bar is realized TypeScript- Polymorphism LED Scrolling text