天天看點

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

java使用内嵌Tomcat開發javaWeb項目

  • 寫在前面
  • 內建Swagger,提供優雅api文檔
    • 在pom.xml添加swagger依賴
    • 建立swagger配置類
    • 在spring-config.xml中配置掃描
    • 在controller下面建立ApiController,用于測試接口描述
    • 在spring-mvc.xml和spring-shiro.xml中開啟swagger資源映射和關閉權限攔截
    • 啟動項目
  • 使用HandlerInterceptor記錄通路controller的日志
    • 編寫LoggingHandlerInterceptor
    • 在spring-mvc.xml中配置
    • 啟動項目
  • 項目部署環境修改
    • 修改啟動類
    • 修改配置檔案加載路徑
    • 修改靜态資源映射路徑
    • 建立與項目同級webapp目錄,遷移檔案到webapp目錄
    • 啟動項目
    • 在pom.xml添加打包插件,将項目打包成可運作的jar包
    • 打包項目
    • 部署項目

寫在前面

這一篇部落格,主要講解項目開發中,接口文檔編寫,日志記錄,項目部署,

java使用内嵌Tomcat開發javaWeb項目-進階篇2這篇部落格,主要講解在開發中,如何內建其他功能,部落格位址:

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇2 ,

java使用内嵌Tomcat開發javaWeb項目源代碼下載下傳位址:

embed-tomcat-example.zip

內建Swagger,提供優雅api文檔

在pom.xml添加swagger依賴

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
...
        <springfox.swagger.version>3.0.0</springfox.swagger.version>
        <swagger.version>1.6.2</swagger.version>
        <jackson.version>2.11.4</jackson.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.swagger/swagger-annotations -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger.version}</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox.swagger.version}</version>
        </dependency>
       <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-oas</artifactId>
            <version>${springfox.swagger.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox.swagger.version}</version>
        </dependency>
		...
           

建立swagger配置類

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
package com.lhstack.embed.config;

import io.swagger.annotations.Api;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author lhstack
 */
@Configuration
@EnableOpenApi
public class SwaggerConfiguration {

    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .ignoredParameterTypes(HttpServletRequest.class,
                        HttpServletResponse.class,
                        HttpSession.class,
                        ServletContext.class,
                        Model.class,
                        ModelAndView.class)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.lhstack.embed.controller")
                        .and(RequestHandlerSelectors.withClassAnnotation(Api.class)))
                .paths(PathSelectors.any())
                .build();
    }

    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .contact(new Contact("lhstack", "https://www.lhstack.com", "[email protected]"))
                .description("embed tomcat")
                .title("embed tomcat")
                .version("0.0.1").build();
    }

}

           

在spring-config.xml中配置掃描

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

在controller下面建立ApiController,用于測試接口描述

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
package com.lhstack.embed.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lhstack
 */
@RestController
@RequestMapping("api")
@Api(tags = "api接口")
public class ApiController {

    @GetMapping("hello")
    @ApiOperation("列印hello")
    public String hello(){
        return "hello";
    }

    @GetMapping("hello/{param}")
    @ApiOperation("帶參數")
    public String hello(@ApiParam(value = "列印的值") @PathVariable("param") String hello){
        return hello;
    }
}

           

在spring-mvc.xml和spring-shiro.xml中開啟swagger資源映射和關閉權限攔截

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
<entry key="/swagger-ui/**" value="anon"/>
<entry key="/swagger-resources/**" value="anon" />
<entry key="/v3/**" value="anon" />
<entry key="/api/**" value="anon" />
           

啟動項目

通過浏覽器輸入

http://localhost:8080/swagger-ui/index.html

,通路swagger穩定,進行接口調試

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

使用HandlerInterceptor記錄通路controller的日志

編寫LoggingHandlerInterceptor

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
package com.lhstack.embed.handler.log;

import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** `
 * @author lhstack
 */
public class LoggingHandlerInterceptor implements HandlerInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingHandlerInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod) handler;

            LOGGER.info("\n" +
                            "--------------\n" +
                            "Method: {}\n" +
                            "Url: {}\n" +
                            "Param: {}\n" +
                            "Handler: {}\n" +
                            "Principal: {}\n" +
                            "--------------",
                    request.getMethod(),
                    request.getRequestURI(),
                    JSONObject.toJSONString(request.getParameterMap()),
                    handlerMethod.getMethod(),
                    SecurityUtils.getSubject().getPrincipal()
            );
        }
        return true;
    }

}


           

在spring-mvc.xml中配置

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.lhstack.embed.handler.log.LoggingHandlerInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
           

啟動項目

通路swagger接口,并請求接口

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

項目部署環境修改

j将配置和靜态資源移動到外部目錄,這是友善項目的配置修改,靜态頁面的修改,如資料庫配置,或者頁面替換等等,提高項目的靈活性,同時也減少了jar包的大小,實作配置,頁面,與背景完全解耦

修改啟動類

修改context path,設定路徑為jar包所在同級目錄下webapp

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

修改spring配置檔案加載路徑,修改為加載contextPath目錄下的WEB-INFO/spring目錄裡面的配置檔案

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
package com.lhstack.embed;

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.websocket.server.WsContextListener;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author lhstack
 */
public class EmbedTomcatApplication {
    public static void main(String[] args) throws Exception {
        int port = 8080;
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(port);
        tomcat.getConnector().setPort(port);
        String webapp = System.getProperty("user.dir") + "/webapp";
        Context context = tomcat.addContext("/", webapp);
        addCharacterFilter(context, "UTF-8");
        addWsContextListener(context);
        addShiroFilter(context);
        addDispatcherServlet(context);
        //啟動tomcat
        tomcat.start();

    }

    private static void addWsContextListener(Context context) {
        context.addApplicationListener(WsContextListener.class.getName());
    }

    private static void addShiroFilter(Context context) {
        DelegatingFilterProxy filterProxy = new DelegatingFilterProxy();
        filterProxy.setTargetFilterLifecycle(true);
        FilterDef filterDef = new FilterDef();
        //這裡與shiroFilterFactoryBean的id必須一緻
        filterDef.setFilterName("shiroFilterFactoryBean");

        filterDef.setFilter(filterProxy);

        //定義filter映射
        FilterMap filterMap = new FilterMap();
        filterMap.setFilterName("shiroFilterFactoryBean");
        filterMap.addURLPattern("/*");
        //添加filter
        context.addFilterDef(filterDef);
        context.addFilterMap(filterMap);
    }

    private static void addDispatcherServlet(Context context) {
        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setContextConfigLocation("WEB-INF/spring/spring-*.xml");
        Wrapper servlet = Tomcat.addServlet(context, "DispatcherServlet", dispatcherServlet);
        //跟着tomcat一起啟動
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }

    private static void addCharacterFilter(Context context, String encoding) {
        //定義filter
        FilterDef filterDef = new FilterDef();
        filterDef.setFilterName("CharacterEncodingFilter");
        filterDef.setFilter((req, res, chain) -> {

            if (req instanceof HttpServletRequest) {
                req.setCharacterEncoding(encoding);
            }
            if (res instanceof HttpServletResponse) {
                res.setCharacterEncoding(encoding);
            }
            chain.doFilter(req, res);
        });

        //定義filter映射
        FilterMap filterMap = new FilterMap();
        filterMap.setFilterName("CharacterEncodingFilter");
        filterMap.addURLPattern("/*");

        //添加filter
        context.addFilterDef(filterDef);
        context.addFilterMap(filterMap);
    }
}

           

修改配置檔案加載路徑

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder location="WEB-INF/config/db.properties,WEB-INF/config/redis.properties" />
    <context:component-scan base-package="com.lhstack.embed.config" />
</beans>
           

修改靜态資源映射路徑

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

建立與項目同級webapp目錄,遷移檔案到webapp目錄

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

啟動項目

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

在pom.xml添加打包插件,将項目打包成可運作的jar包

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
<plugins>
   <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>3.1.0</version>
      <executions>
         <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
               <filters>
                  <filter>
                     <artifact>*:*</artifact>
                     <excludes>
                        <exclude>META-INF/*.SF</exclude>
                        <exclude>META-INF/*.DSA</exclude>
                        <exclude>META-INF/*.RSA</exclude>
                     </excludes>
                  </filter>
               </filters>
               <transformers>
                                <!--               啟動類                 -->
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
				 	 <mainClass>com.lhstack.embed.EmbedTomcatApplication</mainClass>
                  </transformer>
                                <!--                 合并spring jar包下面的META-INF/spring.handlers檔案裡面的内容               -->
    			  <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                     <resource>META-INF/spring.handlers</resource>
                  </transformer>
                                <!--               合并spring jar包下面的META-INF/spring.schemas檔案裡面的内容                 -->
			 	  <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                     <resource>META-INF/spring.schemas</resource>
                  </transformer>
               </transformers>
            </configuration>
          </execution>
        </executions>
  </plugin>
</plugins>
           

打包項目

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

在target目錄下面得到可運作jar包

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

部署項目

将embed-tomcat-example-0.0.1.jar和webapp目錄放在同一個目錄下面,如下

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

jar包裡面也沒有靜态檔案和配置檔案

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

編寫啟動腳本,并放在與jar包同級目錄

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

輕按兩下啟動

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

浏覽器通路

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改
java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

修改靜态資源目錄裡面的内容

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

第一次通路可能有緩存,多試幾次,或者ctrl+f5強制重新整理

java篇-(java使用内嵌Tomcat開發javaWeb項目-進階篇)寫在前面內建Swagger,提供優雅api文檔使用HandlerInterceptor記錄通路controller的日志項目部署環境修改

這樣就實作了使用内嵌tomcat開發項目到部署的過程,同時實作頁面和配置與項目的解耦,保證項目可以随意移植到不同的系統上面運作