Java单体应用创建(Servlet、SpringWeb、SpringMVC、Druid、MyBatis、API)
作者:互联网
文章目录
- 创建项目
- 使用AdminLTE模版创建后台网页
- 添加java代码和servlet
- 使用SpringWeb自动装载ApplicationContext
- 使用SpringMVC和使用注解代替bean节点
- 使用拦截器
- 使用Druid和MyBatis进行数据库访问
- API返回JSON类型数据
创建项目
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问题。
- 【其实是错误解决方案,导致最后点击Debug启动项目时404,正确解决方案看下一条。】解决没有artifact选项问题:1. 选择右侧Maven的Lifecycle的package,双击会自动生成target文件夹(但是我看其他教程没有target文件夹也可以出现artifact所以下次试一下别的方法使之出现artifact),2. File->Project Structure->Artifacts->“+”号->Web Application: Archive->Name改为和target文件夹下的.war同名且不带war后缀->Output directory改为target目录->OK。现在Tomcat Server的Deployment会出现Artifact了。
- 正确解决没有artifact选项问题: 1. 不用生成target目录;2. File->Project Structure->Artifacts->“+”号->Web Application: Exploded->From Modules->选择本项目->OK->OK。
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