项目结构:
main.java.com.smart下:
annotation,自定义注解类
dao(Data Access Object), 数据访问对象包,分为hbase分布式数据库的dao访问包和mybatis框架访问数据库的dao包
domain,领域对象,类似于bean,一般可进行序列化,为SpringMVC中的M层
service,业务层,也是整个项目的最最核心的包,这里保存着整个项目的业务具体细节
web,SpringMVC中的C层,负责处理客户端请求,然后将请求交给service处理
resources下:
i18n,国际化文件包
mybatis,mybatis配置文件包
spring,spring的配置文件包
test.java.com.smart下,测试包
WebContent下:
static,静态文件夹
WEB-INF,这个文件夹的文件是安全的,客户端不能直接访问,需要服务器将请求进行重定向,因此需要一个index.jsp的引导页面
WEB-INF下:
jsp,javaweb的动态网页文件夹
lib,网站外部Java依赖包文件夹
web.xml,网站的主要配置文件,可有可无,详情另行自查资料
1、web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>CloudDesk</display-name>
<!-- 2、SpringMVC配置,配置页面控制器:start-->
<servlet>
<servlet-name>CloudDesk</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:resources/spring/springMVC-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!--大于等于0的整数随服务器启动,整数越小优先级越高-->
</servlet>
<!-- 将javaweb的jsp伪装为html,也可以伪装为任何语言-->
<servlet-mapping>
<servlet-name>CloudDesk</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- 2、SpringMVC配置,配置页面控制器:end-->
<!-- 1、SpringCore配置:start -->
<!-- 作用:ContextLoaderListener的作用就是启动Web容器时,自动装配
ApplicationContext.xml的配置信息,因为它实现了ServletContextListener这个接口 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:resources/spring/ApplicationContext.xml</param-value>
</context-param>
<!-- 1、SpringCore配置:end -->
<!-- 设置字符编码方式 -->
<filter>
<filter-name>setcharacter</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>
</filter>
<filter-mapping>
<filter-name>setcharacter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2、ApplicationContext.xml配置文件(在classpath路径的resources/spring文件下)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" "
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- annotation-config处理@autowired之类的注解(共有四类) 前提是注解作用的类已经被注册到spring容器里(使用这个一般都是先通过xml配置将bean注册<bean id="" class="" />)-->
<!-- component-scan除了包含annotation-config的作用外,还能自动扫描和注册base-package下有@component之类注解的类,将其作为bean注册到spring容器里-->
<!--context:annotation-config/-->
<context:component-scan base-package="main.java.com.smart"/>
</beans>
3、springMVC-servlet.xml配置文件(在classpath路径的resources/spring文件下)
<?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:p="http://www.springframework.org/schema/p"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.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">
<!-- 启动spring MVC 注解 -->
<!-- 设置使用注解的类所在的jar包以及sub package,controller类 -->
<context:component-scan base-package="main.java.com.smart.*" use-default-filters="true">
<!--
<context:include-filter type="annotation" expression=""/>
<context:exclude-filter type="annotation" expression=""/>
-->
</context:component-scan>
</beans>
4、index.jsp页面(过渡页面,这里暂时设定为手动过渡)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首页</title>
</head>
<body>
<div style="margin:0 auto; padding-top: 100px; font-size: 18px;" align="center">
<p><a href="user/ulogin.html">登录系统 </a></p>
</div>
</body>
</html>
5、ulogin.jsp(用户登录页面)(用户页面这里使用了VUE.js前端框架,可自己进行简略)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登录用户桌面</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="User Login Page">
<!--必须使用引入外部WEB-INF下的静态文件,静态文件处于仅为服务器可访问状态,客户端访问需要向服务器进行请求${pageContext.request.contextPath}-->
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/public.css" type="text/css">
<link rel="stylesheet" href="${pageContext.request.contextPath}/static/css/allprivate.css" type="text/css">
</head>
<body>
<div id="container">
<div class="ulogin">
<p class="ulogin_head"><span>用户登录</span></p>
<!--action页面为user/doLogin.html,因为当前使用的为springMVC,可以手动设置映射页面名称,该页面并非真实存在-->
<form class="ulogin_form" onsubmit="return checkUserName()" method="POST" action="user/doLogin.html">
<table>
<tr>
<td>账号</td>
<td><input type="text" name="uid" id="uid" class="ulogin_form_1"
required v-model="uid_text" :placeholder="tip_uid" :maxlength="userlength"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password" id="pwd" class="ulogin_form_1"
required v-model="pwd_text" :placeholder="tip_pwd" :maxlength="pwdlength"></td>
</tr>
</table>
<p class="ulogin_form_line"></p>
<input type="submit" name="登录" class="ulogin_form_2">
<input type="reset" name="重置" class="ulogin_form_2">
</form>
</div>
<div><a href="user/register.html">用户注册</a></div>
<font color="red">${error}</font>
</div>
<script src="${pageContext.request.contextPath}/static/js/vue.min.js"></script>
<script src="${pageContext.request.contextPath}/static/js/login.js"></script>
</body>
6、UserController.java
package main.java.com.smart.web;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import main.java.com.smart.domain.User;
import main.java.com.smart.service.UserService;
@Controller
@RequestMapping("user")
@SessionAttributes("user")//代码中所有名为user的属性全都自动存入session中
public class UserController {
/**
* @Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以
* 设置它的required属性为false,例如:@Autowired(required=false) ,如果我们
* 想使用名称装配可以结合@Qualifier注解进行使用
* @Resource,默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,
* 当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进
* 行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦
* 指定,就只会按照名称进行装配
*/
@Resource
UserService service;
@Resource
HttpServletRequest request;
@RequestMapping("ulogin")
public String toLoginPage(){
return "/WEB-INF/jsp/ulogin.jsp";
}
/**
* 处理用户请求
*
* @param uid
* @param password
* @return
*
* tip:参数consumes={"application/json","text/plain"}指定提交内容类型
* produces="text/plain"指定请求中必须包含某些参数值才会触发这个处理方法
* params="myParam=myValue"指定请求中必须包含某些参数值才会触发这个处理方法
* hearders="content-type=text/*"请求头Header中必须包含某些指定的参数值,才能让该方法处理请求
*/
@RequestMapping(value = "/doLogin", method = RequestMethod.POST)
public String doLogin(@RequestParam Integer uid, @RequestParam String password,ModelMap map){
try {
User user = service.doLoginById(uid,password);
map.put("user", user);
} catch (Exception e) {
request.setAttribute("error", e.getMessage());
return "/WEB-INF/jsp/ulogin.jsp";
}
return "/WEB-INF/jsp/success.jsp";
}
/**
* 退出登录
*
* @param userName
* @param status
* @return
* tip:SessionStatus用于清楚session中的属性一般退出登录时候使用
*/
@RequestMapping("/doLogout")
public String doLogout(String userName,SessionStatus status){
status.setComplete();//清空session内容
return "/WEB-INF/jsp/ulogin.jsp";
}
}
6.UserService.java
package main.java.com.smart.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import main.java.com.smart.dao.mybatis.ibatisDao;
import main.java.com.smart.domain.User;
/**
* 用户业务层
*
* @class main.java.com.smart.service.UserService
* @author ljj
* @date 2018年6月28日
* @notes
*
*/
@Service
public class UserService {
@Resource
ibatisDao msDao; //数据库访问对象
/**
* 通过手机号码登录
*
* @param phone
* @param password
* @return 登录成功返回1
* @throws Exception
*/
public User loginUserByPhone(String phone, String password) throws Exception{
msDao = new ibatisDao();
if(phone == null || "".equals(phone)){
throw new Exception("手机号码不能为空");
}
if (password == null || "".equals(password)) {
throw new Exception("用户密码不能为空");
}
User user = (User)msDao.selectOneM("getUserByPhone", phone);
if(user == null){
throw new Exception("当前用户不存在");
}
if(user.getPassword().equals(password)){
throw new Exception("密码错误");
}
System.out.println(user);
return user;
}
/**
* 通过用户ID登录
*
* @param uid
* @param password
* @return
* @throws Exception
*/
public User doLoginById(Integer uid, String password) throws Exception {
msDao = new ibatisDao();//--需要优化点1
if (uid == null || "".equals(uid)) {
throw new Exception("用户名不能为空");
}
if (password == null || "".equals(password)) {
throw new Exception("密码不能为空");
}
User user = (User)msDao.selectOneM("getUserById", uid);
if (user == null) {
throw new Exception("用户名不存在");
}
if (!user.getPassword().equals(password)) {
throw new Exception("密码错误");
}
System.out.println(user);
return user;
}
public static void main(String[] args) throws Exception {
UserService userService = new UserService();
// userService.loginUserByPhone("111 ", "");
// userService.loginUserByPhone("1542", "123");
userService.doLoginById(111, "111");
}
}
TIP:
1)关于context:annotation-config和context:component-scan,后者包括前者,如果你的bean都是使用xml来定义和配置的话,可以把前者开启,后者不用开启。放弃思考就用后者吧
2)关于@RequestMapping(“user”),如果该注解定义在类名称上,那就是类级的mapping,类内部的所有子RequestMapping接收到的请求的路径前都需要带有user/,这就是为啥上面的ulogin.jsp的的表单action属性值为user/doLogin.html,需要访问user(类级)下的doLogin页面(虚拟)