后端开发基础-SpringMVC框架学习-008——基础概念

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Coder_Boy_/article/details/82932893

系统分层(了解)

为什么要分层

 为了方便系统的维护,方便系统的
性能调优,方便测试,方便分工协作。

如何分层

 表示层:数据的展现和用户操作界面。
 业务层:业务逻辑的处理。
 持久层:数据访问逻辑。
. 表示层调用业务层,业务层调用持久层。
. 下一层为上一层提供某种服务。
. 上一层通过接口调用下一层提供的服务。

表单中文参数值的乱码问题

step1. 确保表单按照post方式提交。
step2. 配置spring提供的
CharacterEncodingFilter过滤器。
step3. 确保页面编码与过滤器配置的编码一致。

练习:
 完成资费列表。
http://ip:port/springcase-netctoss/cost.do
提示:
step1. Cost实体类。
step2. CostDAO接口。
List findAll();
step3. CostDAOJdbcImpl类并测试。
step4. CostService接口。
List list();
step5. CostServiceImpl类并测试。
step6. cost.jsp
注:如果要使用jstl标签,需要导包
step7. CostController

案例演示:

工程案例目录结构

 pom.xml

<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.study</groupId>
  <artifactId>springcase-netctoss</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
  <dependencies>
  	<dependency>
  		<groupId>com.oracle</groupId>
  		<artifactId>ojdbc14</artifactId>
  		<version>10.2.0.4.0</version>
  	</dependency>
  	<dependency>
  		<groupId>commons-dbcp</groupId>
  		<artifactId>commons-dbcp</artifactId>
  		<version>1.4</version>
  	</dependency>
  	<dependency>
  		<groupId>junit</groupId>
  		<artifactId>junit</artifactId>
  		<version>4.12</version>
  	</dependency>
  	 <dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-webmvc</artifactId>
  		<version>3.2.8.RELEASE</version>
  	</dependency>
  </dependencies>
</project>

导入Tomcat类库 

 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>springcase-netctoss</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

	<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>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:app.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>

app.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:jdbc="http://www.springframework.org/schema/jdbc"  
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

		<!-- 配置组件扫描 -->
		<context:component-scan base-package="com.dk.oss"/>
		<!-- 配置mvc注解扫描 -->
		<mvc:annotation-driven/>

		<!-- 
			配置视图解析器:
			负责将视图名解析成真正的视图对象(比如jsp)。
		 -->
		 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		 	<property name="prefix" value="/WEB-INF/"/>
		 	<property name="suffix" value=".jsp"/>
		 </bean>

	<!-- 读取db.properties文件的内容 -->
	<util:properties id="jdbc" location="classpath:db.properties" />
	<!-- 配置DataSource -->
	<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="#{jdbc.driverclass}" />
		<property name="url" value="#{jdbc.url}" />
		<property name="username" value="#{jdbc.user}" />
		<property name="password" value="#{jdbc.password}" />
		<property name="maxActive" value="#{jdbc.maxActive}" />
	</bean>



	
</beans>

db.properties

driverclass=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
user=learn
password=learn
maxActive=1
initSize=1

LoginController.java

package com.dk.oss.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.dk.oss.entity.Admin;
import com.dk.oss.service.AdminService;
import com.dk.oss.service.AppException;

@Controller
public class LoginController {
	
	@Resource(name="adminService")
	private AdminService adminService;
	
	@RequestMapping("/toLogin.do")
	public String toLogin(){
		return "login";
	}

	@RequestMapping("/login.do")
	public String checkLogin(HttpServletRequest request){
		//读取请求参数值
		String adminCode = request.getParameter("adminCode");
		String pwd = request.getParameter("pwd");
		System.out.println("adminCode:"+adminCode+" pwd:"+pwd);
		//调用业务层模块来进行登录处理。
		try{
			Admin admin= adminService.checkLogin(adminCode, pwd);
			System.out.println(admin);//Integer.valueOf("a");
		}catch(Exception e){
			if(e instanceof AppException){
				//应用异常,需要明确提示用户。
				request.setAttribute("errorMsg", e.getMessage());
				System.out.println("自定义异常。。。");
				//转发到登录页面。
				return "login";
			}else{
				//系统异常,提示用户稍后重试。
				System.out.println("系统异常。。。"+e.getMessage());
				return "error";
			}
		}
		//登录成功,重定向到首页。
		return "redirect:index.do";
	}
	
	@RequestMapping("/index.do")
	public String toIndex(){
		return "index";
	}
}

AdminService.java

package com.dk.oss.service;

import com.dk.oss.entity.Admin;

/**
 * 业务层接口
 * 
 * @author Cher_du
 *
 */
public interface AdminService {

	//用于登录处理
	public Admin checkLogin(String code,String pwd);
}

AdminServiceImpl.java

package com.dk.oss.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.dk.oss.dao.AdminDAO;
import com.dk.oss.entity.Admin;
/**
 * 业务层实现
 * @author Cher_du
 *
 */
@Service("adminService")
public class AdminServiceImpl implements AdminService{

	@Resource(name="adminDAO")
	private AdminDAO adminDAO;
	
	public Admin checkLogin(String code, String pwd) {
		//调用AdminDAO访问数据库
		Admin admin = adminDAO.findByCode(code);
		if(admin == null){
			//账户不存在,需要提示用户。
			//抛出一个应用异常(用户在使用系统
			//的过程当中,做了一些错误的操作,比如
			//输出入错误的账户或密码)。
			throw new AppException("账户错误");
		}
		if(!admin.getPassword().equals(pwd)){
			//密码错误,需要提示用户。
			throw new AppException("密码错误");
		}
		//登录成功
		return admin;
	}

}

AppException.java

package com.dk.oss.service;
/**
 * 应用异常类。
 * @author Cher_du
 *
 */
public class AppException extends RuntimeException {

	public AppException() {
		
	}

	public AppException(String message) {
		super(message);
	}


}

AdminDAO.java

package com.dk.oss.dao;

import com.dk.oss.entity.Admin;

/**
 * DAO接口
 *   注:
 *   任何接口,都不要涉及任何具体的实现。
 * @author Cher_du
 *
 */
public interface AdminDAO {

	public Admin findByCode(String code);
}

AdminDAOJdbcImpl.java

package com.dk.oss.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.stereotype.Repository;

import com.dk.oss.entity.Admin;

/**
 * DAO实现类
 * @author Cher_du
 * @Resource默认按照名称方式进行bean匹配,@Autowired默认按照类型方式进行bean匹配
 */
@Repository("adminDAO")
public class AdminDAOJdbcImpl implements AdminDAO{
	//注入datasource。
	@Resource(name="ds")
	private DataSource ds;
	
	public Admin findByCode(String code) {
		Admin admin = null;
		Connection conn = null;
		PreparedStatement prep = null;
		ResultSet rst = null;
		
		try {
			conn = ds.getConnection();
			String sql = "SELECT * FROM admin_info "
						+"WHERE admin_code=?";
			prep = conn.prepareStatement(sql);
			prep.setString(1, code);
			rst = prep.executeQuery();
			if(rst.next()){
				admin = new Admin();
				admin.setAdminId(rst.getInt("admin_id"));
				admin.setAdminCode(rst.getString("admin_code"));
				admin.setPassword(rst.getString("password"));
				admin.setName(rst.getString("name"));
				admin.setTelephone(rst.getString("telephone"));
				admin.setEmail(rst.getString("email"));
				admin.setEnrolldate(rst.getTimestamp("enrolldate"));
			}
			
		} catch (SQLException e) {
			//记日志(保留现场)
			e.printStackTrace();
			/*
			 * 异常能否恢复,如果不能够恢复
			 * (发生了系统异常,比如数据库服务
			 * 暂停,网络中断),则提示用户稍后
			 * 重试。如果能够恢复,则立即恢复。
			 */
			throw new RuntimeException(e);
		}finally{
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
		return admin;
	}
}

Admin.java

package com.dk.oss.entity;

import java.sql.Timestamp;

/**
 * 实体类
 * 注:
 *   与要操作的表保持一致。
 * @author Cher_du
 *
 */
public class Admin {

	private Integer adminId;
	private String adminCode;
	private String password;
	private String name;
	private String telephone;
	private String email;
	private Timestamp enrolldate;
	
	public Integer getAdminId() {
		return adminId;
	}
	public void setAdminId(Integer adminId) {
		this.adminId = adminId;
	}
	public String getAdminCode() {
		return adminCode;
	}
	public void setAdminCode(String adminCode) {
		this.adminCode = adminCode;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTelephone() {
		return telephone;
	}
	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Timestamp getEnrolldate() {
		return enrolldate;
	}
	public void setEnrolldate(Timestamp enrolldate) {
		this.enrolldate = enrolldate;
	}
}

***为了使编写的每一层代码没有问题,需要对其进行单元测试,尽可能减少开发失误。 

TestCase.java

package test;

import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dk.oss.dao.AdminDAO;
import com.dk.oss.dao.CostDAO;
import com.dk.oss.entity.Admin;
import com.dk.oss.entity.Cost;
import com.dk.oss.service.AdminService;

public class TestCase {
	
	@Test
	//测试DataSource
	public void test1() throws SQLException{
		ApplicationContext ac = 
		new ClassPathXmlApplicationContext(
				"app.xml");
		System.out.println(ac);
		DataSource ds= ac.getBean("ds", DataSource.class);
		System.out.println(ds.getConnection());
	}
	
	@Test
	//测试DAO
	public void test2(){
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext(
						"app.xml");
		AdminDAO adminDAO = ac.getBean("adminDAO", AdminDAO.class);
		Admin admin= adminDAO.findByCode("caocao");
		System.out.println(admin.getPassword());
	}
	
	@Test
	//测试AdminService
	public void test3(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("app.xml");
		AdminService adminService = ac.getBean("adminService", AdminService.class);
		Admin admin = adminService.checkLogin("caocao", "123");
		System.out.println(admin.getTelephone());
	}
	
	@Test
	//测试CostDAO
	public void test4(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("app.xml");
		CostDAO dao = ac.getBean("costDAO", CostDAO.class);
		List<Cost> costs = dao.findAll();
		System.out.println(costs);
	}
}

启动Tomcat 运行 springcase-netctoss工程,录入请求http://localhost:8088/springcase-netctoss/toLogin.do

 页面运行结果对应如下 

录入账户与密码的不同情况:

 正确:

错误: 

对应练习 资费Cost部分参考代码: 

Cost.java

package com.dk.oss.entity;

import java.sql.Timestamp;

/**
 * 实体类
 * @author Cher_du
 *
 */
public class Cost {

	private Integer costId;
	private String name;
	//基本时长
	private Integer baseDuration;
	//基本费用
	private Double baseCost;
	//单位费用
	private Double unitCost;
	//状态:0-启用;1-禁用;
	private String status;
	//描述
	private String descr;
	//创建时间
	private Timestamp creatime;
	//开通时间
	private Timestamp startime;
	//资费类型:1-包月;2-套餐;3-计时;
	private String costType;
	
	@Override
	public String toString() {
		return "Cost [costId=" + costId + ", name=" + name + ", baseDuration=" + baseDuration + ", baseCost=" + baseCost
				+ ", unitCost=" + unitCost + ", status=" + status + ", descr=" + descr + ", creatime=" + creatime
				+ ", startime=" + startime + ", costType=" + costType + "]";
	}

	public Integer getCostId() {
		return costId;
	}

	public void setCostId(Integer costId) {
		this.costId = costId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getBaseDuration() {
		return baseDuration;
	}

	public void setBaseDuration(Integer baseDuration) {
		this.baseDuration = baseDuration;
	}

	public Double getBaseCost() {
		return baseCost;
	}

	public void setBaseCost(Double baseCost) {
		this.baseCost = baseCost;
	}

	public Double getUnitCost() {
		return unitCost;
	}

	public void setUnitCost(Double unitCost) {
		this.unitCost = unitCost;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getDescr() {
		return descr;
	}

	public void setDescr(String descr) {
		this.descr = descr;
	}

	public Timestamp getCreatime() {
		return creatime;
	}

	public void setCreatime(Timestamp creatime) {
		this.creatime = creatime;
	}

	public Timestamp getStartime() {
		return startime;
	}

	public void setStartime(Timestamp startime) {
		this.startime = startime;
	}

	public String getCostType() {
		return costType;
	}

	public void setCostType(String costType) {
		this.costType = costType;
	}
	
}

CostDAO.java

package com.dk.oss.dao;

import java.util.List;

import com.dk.oss.entity.Cost;

/**
 * DAO接口
 * @author Cher_du
 *
 */
public interface CostDAO {

	public List<Cost> findAll();
}

CostDAOJdbcImpl.java

package com.dk.oss.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.stereotype.Repository;

import com.dk.oss.entity.Cost;
/**
 * DAO实现类
 * @author Cher_du
 *
 */
@Repository("costDAO")
public class CostDAOJdbcImpl implements CostDAO{

	//注入DataSource
	@Resource(name="ds")
	private DataSource ds;
	
	//查询出所有资费信息
	public List<Cost> findAll() {
		
		List<Cost> costs = new ArrayList<Cost>();
		Connection conn = null;
		PreparedStatement prep = null;
		ResultSet rst = null;
		try {
			conn = ds.getConnection();
			String sql = "SELECT * FROM cost "
						+"ORDER BY cost_id";
			prep = conn.prepareStatement(sql);
			rst = prep.executeQuery();
			while(rst.next()){
				Cost c = createCost(rst);
				costs.add(c);
			}
			
		} catch (SQLException e) {
			
			e.printStackTrace();
			throw new RuntimeException(e);
		}finally{
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
		return costs;
	}

	//将结果集中的记录转换成一个对象
	private Cost createCost(ResultSet rst) throws SQLException {
		Cost c = new Cost();
		c.setCostId(rst.getInt("cost_id"));
		c.setName(rst.getString("name"));
		c.setBaseDuration(rst.getInt("base_duration"));
		c.setBaseCost(rst.getDouble("base_cost"));
		c.setUnitCost(rst.getDouble("unit_cost"));
		c.setStatus(rst.getString("status"));
		c.setDescr(rst.getString("descr"));
		c.setCreatime(rst.getTimestamp("creatime"));
		c.setStartime(rst.getTimestamp("startime"));
		c.setCostType(rst.getString("cost_type"));
		
		return c;
	}

}

猜你喜欢

转载自blog.csdn.net/Coder_Boy_/article/details/82932893