美文网首页
springboot

springboot

作者: 提笔忘字_波 | 来源:发表于2019-05-05 11:17 被阅读0次

    参考文档
    https://www.cnblogs.com/ityouknow/p/5662753.html

    1、Idea 构建项目

    1、选择 File -> New —> Project... 弹出新建项目的框
    2、选择 Spring Initializr,Next 也会出现上述类似的配置界面,Idea 帮我们做了集成
    3、填写相关内容后,点击 Next 选择依赖的包再点击 Next,最后确定信息无误点击 Finish。

    引入 Web 模块

    1、pom.xml中添加支持web的模块:

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
    pom.xml文件中默认有两个模块:
    spring-boot-starter:核心模块,包括自动配置支持、日志和YAML;
    spring-boot-starter-test:测试模块,包括JUnit、Hamcrest、Mockito。
    
    

    2、编写controller内容

    @RestController
    public class HelloWorldController {
        @RequestMapping("/hello")
        public String index() {
            return "Hello World";
        }
    }
    @RestController的意思就是controller里面的方法都以json格式输出,不用再写什么jackjson配置的了!
    
    

    3、如何做单元测试
    打开的src/test/下的测试入口,编写简单的http请求来测试;使用mockmvc进行,利用MockMvcResultHandlers.print()打印出执行结果

     @RunWith(SpringRunner.class)
      @SpringBootTest
    
    public class HelloWorldControlerTests {
        private MockMvc mvc;
        @Before
        public void setUp() throws Exception {
            mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
        }
        @Test
        public void getHello() throws Exception {
    mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    .andDo(MockMvcResultHandlers.print())
                    .andReturn();
        }
    }
    

    4、热加载

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
       </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
       </plugins>
    </build>
    

    2、搭建简单的RESTfull API接口项目

    1、引入依赖
    spring-boot-start-web:搭建springboot项目
    spring-boot-devtools : springboot工具

    2、代码实现

    pom.xml文件

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.4.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    

    实体类

    import java.util.Date;
    /**
     * 实体类
     * 
     * @author wujing
     */
    public class User {
        private int id;
        private String name;
        private Date date;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Date getDate() {
            return date;
        }
        public void setDate(Date date) {
            this.date = date;
        }
    }
    

    controller层

    @RestController //Spring4之后新加入的注解,原来返回json需要@ResponseBody@Controller配合。即@RestController是@ResponseBody和@Controller的组合注解。
    @RequestMapping(value = "/index")
    public class IndexController {
        @RequestMapping
        public String index() {
            return "hello world";
        }
        // @RequestParam 简单类型的绑定,可以出来get和post
        @RequestMapping(value = "/get")
        public HashMap<String, Object> get(@RequestParam String name) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("title", "hello world");
            map.put("name", name);
            return map;
        }
        // @PathVariable 获得请求url中的动态参数
        @RequestMapping(value = "/get/{id}/{name}")
        public User getUser(@PathVariable int id, @PathVariable String name) {
            User user = new User();
            user.setId(id);
            user.setName(name);
            user.setDate(new Date());
            return user;
        }
    }
    

    使用MockMvc测试

    需要引入spring-boot-starter-test这个jar包

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringBootDemo21ApplicationTests {
        private MockMvc mvc;
        @Before
        public void setup() {
            this.mvc = MockMvcBuilders.standaloneSetup(new IndexController()).build();
        }
        @Test
        public void contextLoads() throws Exception {
            RequestBuilder request = get("/index");
        mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("hello world"));
            request = get("/index/get").param("name", "无境");
            mvc.perform(request).andExpect(status().isOk()).andExpect(content().string("{\"name\":\"无境\",\"title\":\"hello world\"}"));
        }
    }
    

    3、配置文件详解--Properties和YAML

    1)配置文件的生效顺序,会对值进行覆盖

    1. @TestPropertySource 注解
    2. 命令行参数
    3. Java系统属性(System.getProperties())
    4. 操作系统环境变量
    5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
    6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
    7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
    8. 在@Configuration类上的@PropertySource注解
    9. 默认属性(使用SpringApplication.setDefaultProperties指定)
    
    
    1. 读取使用注解:@Value(value = "${roncoo.secret}")


      image.png

    3)Application属性文件,按优先级排序,位置高的将覆盖位置低的

    1. 当前目录下的一个/config子目录
    2. 当前目录
    3. 一个classpath下的/config包
    4. classpath根路径(root)
    这个列表是按优先级排序的(列表中位置高的将覆盖位置低的)
    

    4)配置应用端口和其他配置的介绍

    #端口配置:
    server.port=8090
    #时间格式化
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    #时区设置
    spring.jackson.time-zone=Asia/Chongqing
    

    使用YAML代替Properties -> 冒号后要加个空格

    5)多环境配置
    1、创建application.properties、application-dev.properties、application-prod.properties、application-test.properties文件,文件内容如下:

    #主配置文件,配置了这个会优先读取里面的属性覆盖主配置文件的属性
    spring.profiles.active=dev
    #时间格式化
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    #时区设置
    spring.jackson.time-zone=Asia/Chongqing
    

    6)两种配置方式的比较

    1. Properties配置多环境,需要添加多个配置文件,YAML只需要一个配件文件
    2.书写格式的差异,yaml相对比较简洁,优雅
    3. YAML的缺点:不能通过@PropertySource注解加载。如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件。
    

    java -jar myapp.jar --spring.profiles.active=dev


    4、 日志配置

    支持日志框架:Java Util Logging, Log4J2 and Logback,默认是使用logback
    配置方式:默认配置文件配置和引用外部配置文件配置
    

    1、默认配置文件配置(不建议使用:不够灵活,对log4j2等不够友好)

    # 日志文件名,比如:roncoo.log,或者是 /var/log/roncoo.log
    logging.file=roncoo.log 
    # 日志级别配置,比如: logging.level.org.springframework=DEBUG
    logging.level.*=info
    logging.level.org.springframework=DEBUG
    

    2、引用外部配置文件

    spring boot默认会加载classpath:logback-spring.xml或者classpath:logback-spring.groovy
    
    使用自定义配置文件,配置方式为:
    logging.config=classpath:logback-roncoo.xml
    注意:不要使用logback这个来命名,否则spring boot将不能完全实例化
    
    1.使用基于spring boot的配置
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="org.springframework.web" level="DEBUG"/>
    </configuration>
    
    

    3、log4j配置
    3.1去除logback的依赖包,添加log4j2的依赖包

    <dependency>
        <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
    </dependency>
    <!-- 使用log4j2 -->
    <dependency>
            <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    

    3.2在classpath添加log4j2.xml或者log4j2-spring.xml(spring boot 默认加载)

    应用自定义配置

    logging.config=classpath:log4j2-dev.xml
    3.3 log4j2配置文件内容

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <properties>
            <!-- 文件输出格式 -->
            <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} |-%-5level [%thread] %c [%L] -| %msg%n</property>
        </properties>
        <appenders>
            <Console name="CONSOLE" target="system_out">
                <PatternLayout pattern="${PATTERN}" />
            </Console>
        </appenders>
        <loggers>
            <logger name="com.roncoo.education" level="debug" />
            <root level="info">
                <appenderref ref="CONSOLE" />
            </root>
        </loggers>
    </configuration>
    

    3.4 java中引入

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
    logger.debug("this is a log test, debug");
    logger.info("this is a log test, info");
    

    5、错误处理

    1)Spring Boot 将所有的错误默认映射到/error, 实现ErrorController

    @Controller
    @RequestMapping(value = "error")
    public class BaseErrorController implements ErrorController {
    private static final Logger logger = LoggerFactory.getLogger(BaseErrorController.class);
        @Override
        public String getErrorPath() {
            logger.info("出错啦!进入自定义错误控制器");
            return "error/error";
        }
        @RequestMapping
        public String error() {
            return getErrorPath();
        }
    }
    
    

    2)添加自定义的错误页面

    html静态页面:在resources/public/error/ 下定义
    如添加404页面: resources/public/error/404.html页面,中文注意页面编码
    模板引擎页面:在templates/error/下定义
    如添加5xx页面: templates/error/5xx.ftl
    注:templates/error/ 这个的优先级比较 resources/public/error/高
    

    3)使用注解@ControllerAdvice

           /**
         * 统一异常处理
         * 
         * @param exception
         *            exception
         * @return
         */
        @ExceptionHandler({ RuntimeException.class })
        @ResponseStatus(HttpStatus.OK)
        public ModelAndView processException(RuntimeException exception) {
            logger.info("自定义异常处理-RuntimeException");
            ModelAndView m = new ModelAndView();
            m.addObject("exception", exception.getMessage());
            m.setViewName("error/500");
            return m;
        }
        /**
         * 统一异常处理
         * 
         * @param exception
         *            exception
         * @return
         */
        @ExceptionHandler({ Exception.class })
        @ResponseStatus(HttpStatus.OK)
        public ModelAndView processException(Exception exception) {
            logger.info("自定义异常处理-Exception");
            ModelAndView m = new ModelAndView();
            m.addObject("roncooException", exception.getMessage());
            m.setViewName("error/500");
            return m;
        }
    

    6、Servlets, Filters, listeners

    Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet、 >Filter、 Listener 等等
    1) spring boot 中的三种实现方式
    方法一:通过注册 ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制

    /**
    * 自定义 servlet *
    * @author wujing 
    */
    public class CustomServlet extends HttpServlet {
    /** *
       */
      private static final long serialVersionUID = 1L;
      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         System.out.println("servlet get method");
         doPost(request, response);
    }
      @Override
      protected void doPost(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         System.out.println("servlet post method");
         response.getWriter().write("hello world");
    } }
    /**
    * 自定义 filter *
    * @author wujing 
    */
    public class CustomFilter implements Filter {
      @Override
      public void init(FilterConfig filterConfig) throws ServletException {
         System.out.println("init filter");
      }
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
             throws IOException, ServletException {
         System.out.println("do filter");
         chain.doFilter(request, response);
    }
      @Override
      public void destroy() {
         System.out.println("destroy filter");
      }
    }
    /**
    * 自定义 listener *
    * @author wujing */
    public class CustomListener implements ServletContextListener {
      @Override
      public void contextInitialized(ServletContextEvent sce) {
         System.out.println("contextInitialized");
      }
      @Override
      public void contextDestroyed(ServletContextEvent sce) {
         System.out.println("contextDestroyed");
      }
    }
    @Bean
      public ServletRegistrationBean servletRegistrationBean() {
         return new ServletRegistrationBean(new CustomServlet(), "/roncoo");
      }
      @Bean
      public FilterRegistrationBean filterRegistrationBean() {
         return new FilterRegistrationBean(new CustomFilter(), servletRegistrationBean());
      }
      @Bean
      public ServletListenerRegistrationBean<CustomListener> servletListenerRegistrationBean() {
    return new ServletListenerRegistrationBean<CustomListener>(new CustomListener()); 
    }
    

    方法二:通过实现 ServletContextInitializer 接口直接注册

    public class SpringBootDemo102Application implements ServletContextInitializer {
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            servletContext.addServlet("customServlet", new CustomServlet()).addMapping("/roncoo");
            servletContext.addFilter("customFilter", new CustomFilter())
                .addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true, "customServlet");
            servletContext.addListener(new CustomListener());
        }
        public static void main(String[] args) {
            SpringApplication.run(SpringBootDemo102Application.class, args);
        }
    }
    

    方法三:在 SpringBootApplication 上使用@ServletComponentScan 注解后,直接通过@WebServlet、 @WebFilter、@WebListener 注解自动注册

    文件一:
    @ServletComponentScan
    @SpringBootApplication
    public class SpringBootDemo103Application {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootDemo103Application.class, args);
        }
    }
    CustomFilter:
    @WebFilter(filterName = "customFilter", urlPatterns = "/*")
    public class CustomFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init filter");
        }
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("do filter");
            chain.doFilter(request, response);
        }
        @Override
        public void destroy() {
            System.out.println("destroy filter");
        }
    }
    CustomListener:
    @WebListener
    public class CustomListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("contextInitialized");
        }
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("contextDestroyed");
        }
    }
    CustomServlet:
    @WebServlet(name = "customServlet", urlPatterns = "/roncoo")
    public class CustomServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            System.out.println("servlet get method");
            doPost(request, response);
        }
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            System.out.println("servlet post method");
            response.getWriter().write("hello world");
            response.flushBuffer();
        }
    }
    

    HttpServlet
    Filter
    ServletContextListener

    7、CORS 支持

    全局配置:
    @Configuration
    public class CustomCorsConfiguration {
      @Bean
      public WebMvcConfigurer corsConfigurer() {
         return new WebMvcConfigurerAdapter() {
             @Override
             public void addCorsMappings(CorsRegistry registry) {
                  registry.addMapping("/api/**").allowedOrigins("http://localhost:8080");
      } };
    } }
    /**
    * 全局设置
    *
    * @author wujing */
    @Configuration
    public class CustomCorsConfiguration2 extends WebMvcConfigurerAdapter {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/api/**").allowedOrigins("http://localhost:8080");
      }
    }
    细粒度配置
    
    /**
    * @author wujing
    */
    @RestController
    @RequestMapping(value = "/api", method = RequestMethod.POST)
    public class ApiController {
        @CrossOrigin(origins = "http://localhost:8080")
        @RequestMapping(value = "/get")
        public HashMap<String, Object> get(@RequestParam String name) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("title", "hello world");
            map.put("name", name);
            return map;
        } 
    }
    
    

    8、文件上传

    @Controller
    @RequestMapping(value = "/file")
    public class FileController {
        private static final Logger logger = LoggerFactory.getLogger(FileController.class);
        @RequestMapping(value = "upload")
        @ResponseBody
        public String upload(@RequestParam("roncooFile") MultipartFile file) {
            if (file.isEmpty()) {
                return "文件为空";
            }
            // 获取文件名
            String fileName = file.getOriginalFilename();
            logger.info("上传的文件名为:" + fileName);
            // 获取文件的后缀名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            logger.info("上传的后缀名为:" + suffixName);
            // 文件上传路径
            String filePath = "./images/";
            // 解决中文问题,liunx下中文路径,图片显示问题
            // fileName = UUID.randomUUID() + suffixName;
            File dest = new File(filePath + fileName);
            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {
                file.transferTo(dest);
                return "上传成功";
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "上传失败";
        }
    }
    
    浏览器内容:
    <form method="POST" enctype="multipart/form-data" action="/file/upload"> 
         文件:<input type="file" name="roncooFile" />
          <input type="submit" value="上传" />
    </form>
    

    9、事务

    Transactional

    10 、 发送邮件

    1、添加依懒

    <!-- mail -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    

    2、配置

    # mail
    spring.mail.host: smtp.exmail.qq.com
    spring.mail.username:fengyw@roncoo.com,service@roncoo.com,education@roncoo.com
    spring.mail.password:
    spring.mail.properties.mail.smtp.auth: true
    

    3、代码实现

    /**
     * 实现多账号,轮询发送
     * 
     * @author wujing
     */
    @Configuration
    @EnableConfigurationProperties(MailProperties.class)
    public class RoncooJavaMailSenderImpl extends JavaMailSenderImpl implements JavaMailSender {
        private ArrayList<String> usernameList;
        private ArrayList<String> passwordList;
        private int currentMailId = 0;
        private final MailProperties properties;
        public RoncooJavaMailSenderImpl(MailProperties properties) {
            this.properties = properties;
    
            // 初始化账号
            if (usernameList == null)
                usernameList = new ArrayList<String>();
            String[] userNames = this.properties.getUsername().split(",");
            if (userNames != null) {
                for (String user : userNames) {
                    usernameList.add(user);
                }
            }
            // 初始化密码
            if (passwordList == null)
                passwordList = new ArrayList<String>();
            String[] passwords = this.properties.getPassword().split(",");
            if (passwords != null) {
                for (String pw : passwords) {
                    passwordList.add(pw);
                }
            }
        }
        @Override
        protected void doSend(MimeMessage[] mimeMessage, Object[] object) throws MailException {
    
            super.setUsername(usernameList.get(currentMailId));
            super.setPassword(passwordList.get(currentMailId));
    
            // 设置编码和各种参数
            super.setHost(this.properties.getHost());
            super.setDefaultEncoding(this.properties.getDefaultEncoding().name());
            super.setJavaMailProperties(asProperties(this.properties.getProperties()));
            super.doSend(mimeMessage, object);
    
            // 轮询
            currentMailId = (currentMailId + 1) % usernameList.size();
        }
        private Properties asProperties(Map<String, String> source) {
            Properties properties = new Properties();
            properties.putAll(source);
            return properties;
        }
        @Override
        public String getUsername() {
            return usernameList.get(currentMailId);
        }
    }
    

    4、实现发送功能

    @Component
    public class RoncooJavaMailComponent {
        private static final String template = "mail/roncoo.ftl";
        @Autowired
        private FreeMarkerConfigurer freeMarkerConfigurer;
        @Autowired
        private RoncooJavaMailSenderImpl javaMailSender;
    
        public void sendMail(String email) {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("email", email);
            try {
                String text = getTextByTemplate(template, map);
                send(email, text);
            } catch (IOException | TemplateException e) {
                e.printStackTrace();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
        private String getTextByTemplate(String template, Map<String, Object> model) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
            return FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfigurer.getConfiguration().getTemplate(template), model);
        }
        private String send(String email, String text) throws MessagingException, UnsupportedEncodingException {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            InternetAddress from = new InternetAddress();
            from.setAddress(javaMailSender.getUsername());
            from.setPersonal("龙果学院", "UTF-8");
            helper.setFrom(from);
            helper.setTo(email);
            helper.setSubject("测试邮件");
            helper.setText(text, true);
            javaMailSender.send(message);
            return text;
        }
    }
    

    flt代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <div style="width: 600px; text-align: left; margin: 0 auto;">
            <h1 style="color: #005da7;">龙果学院</h1>
            <div style="border-bottom: 5px solid #005da7; height: 2px; width: 100%;"></div>
            <div style="border: 1px solid #005da7; font-size: 16px; line-height: 50px; padding: 20px;">
                <div>${email},您好!</div>
                <div>
                    这是个测试
                </div>
                
                <div style="border-bottom: 2px solid #005da7; height: 2px; width: 100%;"></div>
                <div>扫一扫,关注龙果学院微信公共号,里面更多精彩推荐</div>
                <div>
                    <img src="http://account.roncoo.com/images/qrcode.png" alt="龙果学院公众号二维码" />
                </div>
                <div>
                    想了解更多信息,请访问 <a href="http://www.roncoo.com">http://www.roncoo.com</a>
                </div>
            </div>
        </div>
    </body>
    </html>
    

    html、js代码

    <input type="text" name="email" id="email" />
    <button id="send">发送邮件</button>
    
    $(function(){
        $('#send').click(function(){
            var email = $('#email').val();
            $.ajax({
                url:'/api/mail',
                type:'post',
                data:{'email':email},
                success:function(msg){
                    alert(msg);
                }
            });
        });
    })
    

    java代码

    @Autowired
    private RoncooJavaMailComponent component;
    @RequestMapping(value = "mail")
        public String mail(String email) {
            component.sendMail(email);
            return "success";
        }
    

    相关文章

      网友评论

          本文标题:springboot

          本文链接:https://www.haomeiwen.com/subject/xhrcoqtx.html