天天看点

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开发项目到部署的过程,同时实现页面和配置与项目的解耦,保证项目可以随意移植到不同的系统上面运行