编程语言
首页 > 编程语言> > Java单体应用创建(Servlet、SpringWeb、SpringMVC、Druid、MyBatis、API)

Java单体应用创建(Servlet、SpringWeb、SpringMVC、Druid、MyBatis、API)

作者:互联网

文章目录

创建项目

1、创建一个空目录,名称为项目名如CBDJ,打开IntelliJ IDEA点击Open选择这个目录打开项目。
2、右键项目主目录CBDJ(里面包含一个.idea目录),选择New->File,输入文件名pom.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.crx</groupId>
    <artifactId>cbdj</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>
</project>

groupId为自己公司id,artifactId为项目名称,单词之间用“-”连接,是Java Web项目所以packaging为war。

3、如果右侧栏没有maven面板,则右键pom文件add as maven project。或者重新打开项目,右下角会有提示“Non-managed pom.xml file found: xx Add as Maven Project or Disable notification”,点击“Add as Maven Project”。
4、在dependencies中添加junit和spring-context:

<dependency>
	<groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
	<version>4.3.17.RELEASE</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

5、完善maven的目录结构:
(1)右键CBDJ目录选择New->Directory,添加src/main/java目录,并且mark directory as -> sources root;
(2)添加main下的resources目录,并且mark directory as -> resources root;
(3)main下添加webapp目录;
(4)webapp下添加WEB-INF目录;
(5)WEB-INF下添加web.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
         
</web-app>

6、完善架构结构:
(1)webapp下添加assets目录;
(2)右键java目录选择New->Package,添加名称为com.crx.cbdj的package包;
(3)com.crx.cbdj下添加dao包、service包、web包。
7、src下添加test/java,并且mark directory as -> test sources root。
8、配置spring和log4j:
(1)在main/resources中创建spring-context.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"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

(2)在resources中添加log4j.properties:

log4j.rootLogger=INFO, console, file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.MaxFileSize=1024KB
log4j.appender.A3.MaxBackupIndex=10
log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n

9、添加bootstrap和jquery:
(1) assets中添加plugins目录。
(2)plugins中添加bootstrap目录,去bootstrap官网下载bootstrap,但是这个网站是最新版的,为了兼容没有用最新版而用3.3.7版本,去bootstrap中文网,点击“Bootstrap3中文文档”,点击“下载Bootstrap”跳转页面之后点击“用于生产环境的Bootstrap->下载Bootstrap”。下载了“bootstrap-3.3.7-dist.zip”之后解压,将里面的js、css、font目录复制到plugins/bootstrap中,先“拷贝”这三个目录,然后右键bootstrap目录的Paste,弹出“Copy specified directories”,保持勾选“open in editor”,点击“refactor”,会有一个indexing进度条然后打开bootstrap.css文件。
(3)使用bootstrap是需要用到jQuery,去jQuery官网下载3.3.1版本的min.js(网站打开太慢可以百度搜索去这个网站下载),然后将jquery-3.3.1.min.js直接拷贝到plugins目录下。

10、webapp下创建一个index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    hello cbdj
</body>
</html>

11、Run->Edit Configurations->“+”号->Tomcat Server->Local(IntelliJ IDEA CE版没有Tomcat Server选项),如果“Server->Application server”还没有配置tomcat的版本(下图已配置),则要先下载tomcat。
在这里插入图片描述
11.1 下载安装tomcat
(1)下载安装tomcat:去tomcat官网,选择比如9.0.39版本下的Binary Distributions下的Core的tar.gz,解压后的目录可以放到“/Users/用户名/”目录下,进入解压包的bin目录下执行“./startup.sh”(如果提示没权限则“chmod u+x startup.sh”加执行权限)。浏览器输入“http://localhost:8080”如果能打开带有tomcat的logo的网页则表示启动成功,关闭在bin目录下执行“./shutdown.sh”。
(2)已经安装tomcat且关闭之后,可以配置“Server->Application server”,点击Application server右边的configure,在弹出的“Tomcat Server”窗口的“Tomcat Home”选择tomcat的解压包目录,窗口后面的选项比如Tomcat base directory会自动填充。
(3)配置好“Application server”之后,默认勾选“After launch 谷歌图标Default”、url为“http://localhost:8080”、on update action为“Restart server”勾选“show dialog”、JRE“Default”、HTTP port为“8080”、Before launch“Build”、勾选“Activate tool window”。这是首次配置“Application server”,在HTTP port后面没有JMX port默认为“1099”的选项,第二次打开会出现。

11.2 配置IntelliJ IDEA的项目的tomcat时如果Deployment的+没有artifact
点击“Deployment”(点击Tomcat Server->Local之后弹出的配置窗口中的第二个tab),点击“+”号选择artifact,如果没有找到这个选项且只有“external source”,则先解决artifact问题。

11.3 前面两个配置正确之后,开始配置IntelliJ IDEA的项目的tomcat
在这里插入图片描述
(1)填写name为cbdj,点击“Deployment”,点击“+”号->Artifact,选择“CBDJ:war exploded”。
(2)更改“Server”->“on update action”和“on frame deactivation”为“update classes and resources”,点击“Apply”,点击OK。

12、配置JDK:点击右上角倒数第三个按钮,弹出Project Structure窗口,如果Project Settings->Project下的Project SDK为空,就要选择一下SDK版本,比如SDK1.8,Project language level选择8,点击OK。
在这里插入图片描述13、点击右上角小虫子Debug按钮,会启动Tomcat Server并且在浏览器中打开网页,网页地址是“http://localhost:8080/CBDJ_war_exploded/”,是Debug Configurations配置tomcat时的URL。(前面的配置要一样,否则启动Tomcat Server时会出现错误不会自动打开网页,比如如果忘了在web.xml文件中写入内容就会启动出错。)
在这里插入图片描述
在这里插入图片描述
如果启动时失败,错误提示“Port already in use: 1099”,则之前启动这个应用还没有关闭,执行“lsof -i :1099”查看占用这个端口的PID,然后“kill -9 进程PID”,重新点击debug按钮就不会再报这个错误。或者,到tomcat的安装目录的bin下执行“./shutdown.sh”关闭tomcat服务器。

14、添加.gitignore文件,然后将代码上传到GitHub:

.DS_Store
target/
/.idea/

使用AdminLTE模版创建后台网页

1、去adminlte.io点击Download跳转到GitHub下载release->assets下的Source code(zip),选择2.4.3版本。
2、在解压包中双击index.html打开模版网页,可以选择需要的网页、样式复制,比如左侧Examples的Login登录页面,在网址栏可以看到这个login.html文件位置。
3、将CBDJ项目的webapp->assets下的plugins删掉,将2.4.3版本下的bower_components目录复制到assets下(复制过程有点卡,等一会才出现indexing),将dist下的三个目录(不是dist目录)复制到assets下,将plugins目录复制到assets下。
4、打开login.html文件,复制里面的内容到index.jsp文件中,但是要保留jsp文件第一行<%@ page contentType="text/html;charset=UTF-8" language="java" %>,后面的内容替换成<!DOCTYPE html>...,而且有些代码需要删掉,有些需要修改,比如原本是<link rel="stylesheet" href="../../bower_components/bootstrap/dist/css/bootstrap.min.css">改成<link rel="stylesheet" href="assets/bower_components/bootstrap/dist/css/bootstrap.min.css">

添加java代码和servlet

1、com.crx.cbdj下添加一个名为entity的package包,在entity右键New->Java Class创建一个名为User的Class,实现Serializable接口因为要在网络中传输,添加几个成员变量,右键代码编辑区域选择generate->getter and setter,全选成员变量,点击OK。

package com.crx.cbdj.entity;
import java.io.Serializable;
public class User implements Serializable {
    private String username;
    private String password;
    private String email;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

2、在dao包下右键New->Java Class创建一个名为UserDao的Interface,添加一个方法,并且在dao下创建一个包impl,impl下创建一个类叫UserDaoImpl实现UserDao接口。

package com.crx.cbdj.dao;
import com.crx.cbdj.entity.User;
public interface UserDao {
    public User getUser(String email, String password);
}
package com.crx.cbdj.dao.impl;
import com.crx.cbdj.dao.UserDao;
import com.crx.cbdj.entity.User;
public class UserDaoImpl implements UserDao {
    public User getUser(String email, String password) {
        User user = null;
        if ("admin@qq.com".equals(email) && "123".equals(password)) {
            user = new User();
            user.setUsername("admin");
            user.setEmail(email);
        }
        return user;
    }
}

3、service包下创建一个Interface名称为UserService,添加方法如login,包下创建一个impl包,impl里面创建一个Class名称为UserServiceImpl,实现UserService接口,具体代码如(3)。(dao是数据访问层,service是业务层。)

package com.crx.cbdj.service;
import com.crx.cbdj.entity.User;
public interface UserService {
    public User login(String email, String password);
}

(1)在spring-context.xml中<beans></beans>之间添加<bean id="userDao" class="com.crx.cbdj.dao.impl.UserDaoImpl" />
(2)com.crx.cbdj下创建一个包common.context,创建一个SpringContext类:

package com.crx.cbdj.common.context;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class SpringContext {
    public Object getBean(String beanId) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        return context.getBean(beanId);
    }
}

(3)使用bean获取一个实例:修改UserServiceImpl如下:

package com.crx.cbdj.service.impl;
import com.crx.cbdj.common.context.SpringContext;
import com.crx.cbdj.dao.UserDao;
import com.crx.cbdj.entity.User;
import com.crx.cbdj.service.UserService;
public class UserServiceImpl implements UserService {
    public User login(String email, String password) {
        SpringContext context = new SpringContext();
        UserDao userDao = (UserDao) context.getBean("userDao");
        return userDao.getUser(email, password);
    }
}

4、web包下创建一个controller包,在controller包下创建一个LoginController类,继承自HttpServlet,实现doGet和doPost(直接在类内写doget会自动提示补全)。
(1)需要实例化的类,先在spring-context.xml中添加一个bean,然后再在需要用到实例的地方用ApplicationContext+getBean()获取。
(2)在spring-context.xml中添加<bean id="userService" class="com.crx.cbdj.service.impl.UserServiceImpl" />,在LoginController中添加如下:

package com.crx.cbdj.web.controller;
import com.crx.cbdj.common.context.SpringContext;
import com.crx.cbdj.entity.User;
import com.crx.cbdj.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginController extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String email = req.getParameter("email");
        String password = req.getParameter("password");
        SpringContext context = new SpringContext();
        UserService userService = (UserService) context.getBean("userService");
        User user = userService.login(email, password);
        System.out.println(user);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String email = req.getParameter("email");
        String password = req.getParameter("password");
        SpringContext context = new SpringContext();
        UserService userService = (UserService) context.getBean("userService");
        User user = userService.login(email, password);
        if (user != null) {
            resp.sendRedirect("./main.jsp"); // 如果这里写成"/main.jsp",则路径是"http://localhost:8080/main.jsp",不是"http://localhost:8080/CBDJ_war_exploded/main.jsp"
        } else {
            req.setAttribute("message", "用户名或密码错误"); // 用于在前端页面中使用jsp获取这个数据
            req.getRequestDispatcher("./index.jsp").forward(req, resp);
        }
    }
}

index.jsp部分代码:

 <form action="./login" method="post">
	${message}
    <input name="email" type="email" placeholder="Email">
    <input name="password" type="password" placeholder="Password">
	<button type="submit">Sign In</button>
</form>

(3)日志的使用:在类UserDaoImpl中实例化Logger对象private static final Logger logger = LoggerFactory.getLogger(UserDaoImpl.class);(注意导入的是slf4j的包),使用时logger.debug("调用了 getUser(),参数为{}, {}", email, password); logger.info(""); logger.warn("");
(4)在web.xml的<web-app></web-app>之间添加servlet:

<servlet>
        <servlet-name>LoginController</servlet-name>
        <servlet-class>com.crx.cbdj.web.controller.LoginController</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>LoginController</servlet-name>
        <url-pattern>/login</url-pattern>
</servlet-mapping>

(5)点击debug时如果出现错误“Error:java:错误:不支持发行版本5”,则检查Project Structure->Project Settings的Project和Modules的Language level,检查Preferences的Java Complier的“Target bytecode version”,将1.5修改为8。
在这里插入图片描述
在这里插入图片描述
(6)打开网页时如果出现500错误、404错误,可以在下方Tomcat Localhost Log中看到错误信息。
(7)点击代码编辑区域的行号栏,添加断点,再次点击断点可以删除。

使用SpringWeb自动装载ApplicationContext

1、pom.xml添加spring-web依赖,并且点击Maven面板的第一个按钮刷新,version的红字变成白色:

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.17.RELEASE</version>
</dependency>

在这里插入图片描述
2、web.xml中的web-app之间添加:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
</context-param>
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

3、修改SpringContext类:

package com.crx.cbdj.common.context;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContext implements ApplicationContextAware, DisposableBean {
    private static ApplicationContext applicationContext;
    public static <T> T getBean(String beanId) {
        assertContextInjected();
        return (T) applicationContext.getBean(beanId);
    }
    public static <T> T getBean(Class<T> cls) {
        assertContextInjected();
        return applicationContext.getBean(cls);
    }
    public void destroy() throws Exception {
        applicationContext = null;
    }
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContext.applicationContext = applicationContext;
    }
    private static void assertContextInjected() {
        /*
        注意,是第一个参数的值为false时,才会打印第二个参数的消息,并且抛出异常IllegalStateException,
        所以如果服务器启动没有自动打开网页,Intellij IDEA的下方server打印出"Error during artifact deployment",
        且Tomcat Localhost Log打印出错误"org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService' defined in file [/Users/RC/Documents/ProjectAtWork/CBDJ/target/cbdj-1.0.0-SNAPSHOT/WEB-INF/classes/spring-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.crx.cbdj.service.impl.UserServiceImpl]: Constructor threw exception; nested exception is java.lang.IllegalStateException: ApplicationContext为空",
        则看看是不是错写成"applicationContext==null",
        或者spring-context.xml缺少"<bean id="spring/Context" class="com.crx.cbdj.common.context.SpringContext" />"
        */
        Validate.validState(applicationContext!=null, "ApplicationContext为空");
    }
}

Validate类是一个apache提供的工具类,使用之前要添加依赖:

<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
</dependency>

注意Validate.validState()的第一个参数是“applicationContext!=null”是不等于号,千万不要错写成==号。否则会出现以下错误,且Tomcat Localhost Log打印出错误“org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘userService’ …nested exception is java.lang.IllegalStateException: ApplicationContext为空”(在Validate.validState()这行代码打断点,会发现applicationContext实际并不为空):
在这里插入图片描述
4、spring-context.xml添加:

<bean id="spring/Context" class="com.crx.cbdj.common.context.SpringContext" />

5、修改LoginController和其他使用到bean的地方:

public class LoginController extends HttpServlet {
    private UserService userService = SpringContext.getBean("userService");
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String email = req.getParameter("email");
        String password = req.getParameter("password");
        User user = userService.login(email, password);
    }
}
public class UserServiceImpl implements UserService {
    private UserDao userDao = SpringContext.getBean("userDao");
    public User login(String email, String password) {
        return userDao.getUser(email, password);
    }
}

使用SpringMVC和使用注解代替bean节点

1、去掉spring-context和spring-web的依赖,添加spring-webmvc的依赖,然后刷新一下maven,否则写web.xml时org.springframework.web.下不提示servlet。

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.17.RELEASE</version>
</dependency>

2、WEB-INF下创建一个目录views,将index.jsp和main.jsp移到这个目录,在弹出的窗口中勾选“Search for reference”,点击“Refactor”,index.jsp重命名为login.jsp。
3、src/main/resources下创建一个cbdj.properties:

web.view.prefix=/WEB-INF/views
web.view.suffix=.jsp

4、src/main/resources下创建一个spring-mvc.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <description>Spring MVC Configuration</description>

    <context:property-placeholder ignore-unresolvable="true" location="classpath:cbdj.properties" />

    <!-- 使用Annotation自动注册bean,只扫描@Controller -->
    <context:component-scan base-package="com.crx.cbdj" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <mvc:annotation-driven />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="${web.view.prefix}" />
        <property name="suffix" value="${web.view.suffix}" />
    </bean>

    <mvc:resources mapping="/assets/**" location="/assets/" cache-period="31536000" />
</beans>

5、为了使用注解注入bean,修改spring-context.xml,并且要设置不扫描spring-mvc.xml中已经配置的@Controller:先要删掉beans之间的所有bean节点,还要修改beans的属性增加context,修改后的spring-context.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 http://www.springframework.org/schema/context/spring-context.xsd">
    <context:annotation-config />
    <context:component-scan base-package="com.crx.cbdj">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
</beans>

6、使用注解注入bean,修改原本设置了bean节点的类,在类声明上加上注解:(@Component可以在所有类上使用,@Repository用于对dao实现类进行注解,@Service用于service实现类,@Controller用于controller实现类)。

import org.springframework.stereotype.Component;
@Component
public class SpringContext implements ApplicationContextAware, DisposableBean {
...

import org.springframework.stereotype.Repository;
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao {
...

import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
...

7、修改LoginController,创建MainController:

package com.crx.cbdj.web.controller;
import com.crx.cbdj.entity.User;
import com.crx.cbdj.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;

@Controller
public class LoginController {
    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);
    /*
    自动装载,相当于"private UserService userService = SpringContext.getBean("userService");",
    所以UserServiceImpl的@Service不用设置value。
     */
    @Autowired
    private UserService userService;
    @RequestMapping(value = {"", "login"}, method = RequestMethod.GET)
    public String login() {
        logger.debug("调用了无参数login()方法");
        /*
        如果写成“login”而不是“/login”,则会出现错误“/WEB-INF/viewslogin.jsp未找到“,
        不知道是不是因为tomcat的URL是“http://localhost:8080/CBDJ_war_exploded/”非“http://localhost:8080/”。
         */
        return "/login";
    }
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public String login(@RequestParam(required = true) String email, @RequestParam(required = true) String password, HttpServletRequest req) {
        logger.debug("调用了有参数login()方法");
        User user = userService.login(email, password);
        if (user != null) {
            req.getSession().setAttribute("user", user);
            return "redirect:/main"; // 重定向
        } else {
            req.setAttribute("message", "用户名或密码错误"); // 用于在前端页面中使用jsp获取这个数据
            return login();
        }
    }
}
package com.crx.cbdj.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MainController {
    @RequestMapping(value = "main", method = RequestMethod.GET)
    public String main() {
        return "/main";
    }
}

8、删掉web.xml中的LoginController的servlet和servlet-mapping节点,改为:

	<filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>springServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:/spring-mvc*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

使用拦截器

1、创建拦截器拦截所有路径,除了login和静态资源文件,目的是为了未登录时访问其他路径都重定向到登录页面:
(1)创建LoginInterceptor:

package com.crx.cbdj.web.interceptor;
import com.crx.cbdj.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        User user = (User) httpServletRequest.getSession().getAttribute("user");
        System.out.println("LoginInterceptor preHandle: " + user);
        if (user == null) {
            /*
            不能写成"/login",否则会跳到"http://localhost:8080/login"而不是"http://localhost:8080/CBDJ_war_exploded/login",
            如果tomcat的URL是"http://localhost:8080"可以写成"/login"。
             */
            httpServletResponse.sendRedirect("login");
        }
        return true; // true表示放行
    }
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

(2)在spring-mvc.xml配置拦截器:

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/assets/**"/>
            <bean class="com.crx.cbdj.web.interceptor.LoginInterceptor" />
        </mvc:interceptor>
</mvc:interceptors>

2、创建拦截器拦截login,目的是在已登录时访问登录页面自动重定向到首页:
(1)创建PermissionInterceptor:

package com.crx.cbdj.web.interceptor;
import com.crx.cbdj.entity.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PermissionInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        return true;
    }
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("PermissionInterceptor postHandle");
        /*
         好像如果LoginInterceptor和PermissionInterceptor都进行拦截,
         会先调用后添加到spring-mvc.xml的拦截器,比如先调用PermissionInterceptor。
         */
        if (modelAndView.getViewName().endsWith("login")) {
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            if (user != null) {
                httpServletResponse.sendRedirect("main");
            }
        }
    }
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

(2)在spring-mvc.xml的“mvc:interceptors”之间添加一个“mvc:interceptor”:

<mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.crx.cbdj.web.interceptor.PermissionInterceptor" />
</mvc:interceptor>

使用Druid和MyBatis进行数据库访问

1、添加Druid(数据库连接)的依赖:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

2、创建jdbc.properties:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/cbdj?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=123456
jdbc.pool.init=1
jdbc.pool.minIdle=3
jdbc.pool.maxActive=20
jdbc.testSql=SELECT 'x' FROM DUAL

3、创建spring-context-druid.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 http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc.properties" />
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >
        <property name="driverClassName" value="${jdbc.driverClass}" />
        <property name="url" value="${jdbc.connectionURL}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.pool.init}" />
        <property name="minIdle" value="${jdbc.pool.minIdle}" />
        <property name="maxActive" value="${jdbc.pool.maxActive}" />
        <property name="maxWait" value="60000" />
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="validationQuery" value="${jdbc.testSql}" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="filters" value="stat" />
    </bean>
</beans>

4、配置Druid监控中心,在web.xml中添加以下servlet,就可以通过“http://localhost:8080/CBDJ_war_exploded/druid”访问监控中心:

    <servlet>
        <servlet-name>DruidStatView</servlet-name>
        <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DruidStatView</servlet-name>
        <url-pattern>/druid/*</url-pattern>
    </servlet-mapping>

5、打开mysql服务器,并保证mysql中有要连接的数据库:
(1)打开mysql:已经安装了MySQL会出现在系统偏好设置中,点击MySQL图标进入设置页面,点击“Start MySQL Server”。
(2)创建cbdj数据库:安装MySQLWorkbench,输入URL、用户名和密码连接mysql服务器,然后在打开的数据库连接中点击第四个按钮“create a new schema xx”,输入cbdj为Schema Name(名字要和jdbc.connectionURL中“jdbc:mysql://localhost:3306/cbdj?”问号前面的数据库名一样),Character Set选utf8,Collation选utf8_general_ci。
在这里插入图片描述
(3)创建表:MySQLWorkbench左边SCHEMAS列表中的cbdj,选中cbdj下方的TABLES,右键选择“create table …”,创建表tb_user,包含字段id(INT(11))、username(VARCHAR(45))、password(VARCHAR(45))、email(VARCHAR(45))。
(4)修改UserDao添加userId属性Long类型,添加getter和setter,修改toString。UserDao的属性名和tb_user的字段名一一对应,如果名称不一样,则在mapper.xml文件中要取别名,参看11。

public class User implements Serializable {
    private Long userId;
    private String username;
    private String password;
    private String email;
...

(5)表中添加数据:右键表格tb_user,选择“select rows - limit 1000”,在Result Grid下方的表格中添加几行数据,点击Apply。
6、添加MyBatis(SQL操作)依赖:

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.17.RELEASE</version>
        </dependency>

7、创建MyBatis的配置文件mybatis-config.xml:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" >
<configuration>
    <settings>
        <setting name="cacheEnabled" value="false"/>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="true"/>
        <setting name="multipleResultSetsEnabled" value="true"/>
        <setting name="useColumnLabel" value="true"/>
        <setting name="useGeneratedKeys" value="false"/>
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="localCacheScope" value="SESSION"/>
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>
</configuration>

8、创建spring-context-mybatis.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"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.crx.cbdj.entity" />
        <property name="mapperLocations" value="classpath:/mapper/**/*.xml" />
        <property name="configLocation" value="classpath:/mybatis-config.xml" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
        <property name="basePackage" value="com.crx.cbdj.dao" />
    </bean>
</beans>

9、在src/main/resources目录下创建一个mapper目录。
10、修改UserDao类删掉getUser方法添加getByEmail添加@Repository,删除UserDaoImpl类,修改UserService和UserServiceImpl类。

@Repository
public interface UserDao {
    public User getByEmail(String email);
...

public interface UserService {
    public User login(String email, String password);
...

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    public User login(String email, String password) {
        User user = userDao.getByEmail(email);
        if (user != null) {
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
            if (md5Password.equals(user.getPassword())) {
                return user;
            }
        }
        return null;
    }
...

11、在mapper目录下创建一个UserMapper.xml:(右键MySQLWorkbench的表tb_user,选择“Copy to Clipboard”,选择一项比如Insert Statement就会在剪贴板中复制了插入语句,在UserMapper.xml中Command+V粘贴,然后修改为mapper语法,可以按住option键拖动鼠标进行块选择修改。)

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.crx.cbdj.dao.UserDao">
    <select id="getByEmail" resultType="User">
        SELECT
        a.id AS userId,
        a.username,
        a.password,
        a.email
        FROM
        tb_user AS a
        WHERE
        a.email = #{email}
    </select>
</mapper>

12、使用单元测试测试mybatis:
(1)添加依赖:

		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.17.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

(2)src/test/java目录下创建一个包com.crx.cbdj.service.test,包下创建一个类UserServiceTest,光标停在testLogin函数内部,右键选择“Run ‘testLogin()’”。

package com.crx.cbdj.service.test;
import com.crx.cbdj.entity.User;
import com.crx.cbdj.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.DigestUtils;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-context.xml", "classpath:spring-context-druid.xml", "classpath:spring-context-mybatis.xml"})
// classpath指的是target/cbdj-1.0.0-SNAPSHOT/WEB-INF/classes目录
public class UserServiceTest {
    @Autowired
    private UserService userService;
    @Test
    public void testLogin() {
        User user = userService.login("tom@qq.com", "123456");
        System.out.println(user);
    }
}

API返回JSON类型数据

1、添加jackson依赖,否则无法将返回Java类转换成json数据:

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>

2、添加一个controller类:

package com.crx.cbdj.web.controller;
import com.crx.cbdj.entity.User;
import com.crx.cbdj.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping(value = "business")
public class BusinessController {
    @Autowired
    private UserService userService;
    // 这个方法的请求路径是"http://localhost:8080/CBDJ_war_exploded/business/findUserByName?username=a"
    @RequestMapping(value = "findUserByName", method = RequestMethod.GET)
    public List<User> findUserByName(String username) {
        return userService.selectByUsername(username);
        // 必须依赖jackson-core和jackson-databind,否则无法将List自动转化成JSON格式,会500错误提示"No converter found for return value of type: class java.util.ArrayList"
    }
}

3、修改spring-mvc.xml,在LoginInterceptor和PermissionInterceptor的mvc:interceptor标签之间添加<mvc:exclude-mapping path="/business/**"/>,使xx/business/findUserByNamexx请求不经过这两个拦截器。

参考资料:
Java单体应用视频教程

标签:cbdj,Java,String,SpringMVC,SpringWeb,org,import,com,public
来源: https://blog.csdn.net/rccrx/article/details/114384382