第一大题:

第一小问:Java EE的应用模式:把相应的技术填到相应的层,Web(展示层)、Action(控制层)、Service(服务层,业务逻辑层)、Dao(数据访问层)分层。

参考:
根据Java EE的四层模型原理,将servlet,jsp,JavaBean,mvc,dao,jdbc,Struts2,hibernate5,spring5等技术或框架填入JavaEE模型各层次中:
1.1客户层:mvc
1.2 web层:servlet,Struts2,jsp
1.3业务层:JavaBean,spring5
1.4 EIS层:dao,hibernate5,jdbc

第二个小问,MVC(分别是什么)。模型与控制器之间的调用方法是什么?

参考:
根据mvc设计模式原理,解析三者之间调用关系。模型封装应用程序状态、响应状态查询、应用程序功能、通知视图改变;视图解释模型、模型更新请求、发送用户输入给控制器、允许控制器选择视图;控制器定义应用程序行为、用户动作映射成模型更新、选择响应的视图。
2.1控制器与模型间的方法调用是:状态改变。
2.2模型与视图间的方法调用和事件分别是:状态查询、通知改变
2.3视图与控制器间的方法调用和事件分别是:视图选择、用户请求
在这里插入图片描述

过滤器和拦截器的区别:

struts框架执行顺序(视频里面有):
参考:
根据Struts2框架及其工作原理,解析其工作流程。
①ActionProxy创建一个ActionInvocation实例。
②客户端浏览器发送请求,客户端初始化一个指向servlet容器(如Tomcat);
③接着核心控制器FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决
④⑤⑥⑦⑧⑨
②⑥③⑤④①⑨⑦⑧

根据hibernate5框架,编写其工作过程的关键步骤代码。

4.1构建configuration实例:Configuration cfg=new Configuration().configure();
4.2创建sessionFactory实例:SessionFactory sf=cfg.buildSessionFactory();
4.3创建session实例:Session session =sf.openSession();
4.4开启事务:Transaction tx = session.beginTransaction();
4.5 session接口提供操作数据库(任意方法):session.save(user);
4.6提交事务:tx.commit();
4.7回滚事务:tx.rollback();
4.8关闭session:session.close();
4.9关闭sessionFactory:sf.close();

Hibernate框架5点:HQL、QBC两个查询作比较。

HQL查询:

参考:

package top.jacktgq.hibernate.demo1;

import java.util.Arrays;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import top.jacktgq.hibernate.domain.Customer;
import top.jacktgq.hibernate.domain.LinkMan;
import top.jacktgq.hibernate.utils.HibernateUtils;

/**
 * 
 * @author 糖果墙
 *
 */
public class HibernateDemo1 {

@Test
/**
* 初始化数据
*/
public void demo1() {
/*Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//创建一个客户
Customer customer = new Customer();
customer.setCust_name("靓仔");
for(int i=0;i<10;i++) {
LinkMan linkman = new LinkMan();
linkman.setLkm_name("旺财"+i);
linkman.setCustomer(customer);
customer.getLinkMans().add(linkman);
session.save(linkman);
}
session.save(customer);

transaction.commit();*/
}
@Test
/**
* HQL的简单查询
*/
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

Query query = session.createQuery("from Customer");
List<Customer> list = query.list();

//sql中支持*的写法:select * from cst_customer;但在HQL中不支持*号的写法

for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* HQL别名查询
*/
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

Query query = session.createQuery("select c from Customer c");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* HQL排序查询
*/
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//排序查询
//默认是升序
//List<Customer> list = session.createQuery("from Customer").list();
//List<Customer> list = session.createQuery("from Customer order by cust_id").list();
//设置降序排序
List<Customer> list = session.createQuery("from Customer order by cust_id desc").list();

for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}

@Test
/**
* HQL条件查询
*/
public void demo5() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//条件查询
//一、按位置绑定:更具参数的位置进行绑定。
/*Query query = session.createQuery("from Customer where cust_name=?");
query.setParameter(0,"唐锦涛");
List<Customer> list = query.list();*/
//二、按名称绑定
		Query query = session.createQuery("from Customer where cust_source = :aaa and cust_name = :bbb"); 
//设置参数:
query.setParameter("aaa","朋友推荐");
query.setParameter("bbb","王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}

@Test
/**
* 投影查询
*/
public void demo6() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//投影查询
//单个属性
/*Query query = session.createQuery("select c.cust_name from Customer c");
List list = query.list();
for (Object cust_name : list) {
System.out.println(cust_name);
}*/

//多个属性
/*List<Object[]> obj = session.createQuery("select c.cust_name,c.cust_source from Customer c").list();
for (Object[] objects : obj) {
System.out.println("cust_name:"+objects[0]+",cust_source:"+objects[1]);
}*/

//查询多个属性,但是我想封装到对象中
List<Customer> list = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}

@Test
/**
* HQL分页查询
*/
public void demo7() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//分页查询
Query query = session.createQuery("from LinkMan");
		query.setFirstResult(11); 
query.setMaxResults(10);
List<LinkMan> list = query.list();
for (LinkMan linkman : list) {
System.out.println(linkman);
}

transaction.commit();
}

@Test
/**
* 分组统计查询
*/
public void demo8() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//聚合函数的使用:count(),max(),min(),avg(),sum()
/*Object count = session.createQuery("select count(*) from Customer").uniqueResult();
System.out.println(count);*/
//分组统计
List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source").list();
for (Object[] object : list) {
System.out.println("客户信息源:"+object[0]+",客户数量:"+object[1]);
}
transaction.commit();
}

@Test
/**
* HQL多表查询
*/
public void demo9() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//HQL:select * from cst_customer c inner join cst_linkman l on c.cust_id=l.lkm_cust_id
//HQL:内连接
/*List<Object[]> list = (List<Object[]) session.createQuery("from Customer c inner join c.linkMans").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}*/
//HQL:迫切内连接 其实就是普通inner join后添加一个关键字fetch。 from Customer c inner join fetch c.linkMans
//fetch的作用:通知hibernate,将另一个对象的数据封装到该对象的集合中
List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}
}

QBC查询:

参考:

package top.jacktgq.hibernate.demo1;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

import top.jacktgq.hibernate.domain.Customer;
import top.jacktgq.hibernate.utils.HibernateUtils;

/**
 * QBC查询
 * @author 糖果墙
 *
 */
public class HibernateDemo2 {
@Test
/**
* 简单的查询
*/
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//获得Criteria
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* 排序查询
*/
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//排序查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* 分页查询
*/
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//分页查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(5);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* 条件查询
*/
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

//条件查询
Criteria criteria = session.createCriteria(Customer.class);
//设置条件
/**
* = eq
* > gt
* >= ge
* < lt
* <= le
* <> ne
* like
* in
* and
* or
*/
criteria.add(Restrictions.eq("cust_source", "朋友推荐"));
//默认是and条件,改成or需要指定
//criteria.add(Restrictions.or(Restrictions.like("cust_name", "王%")));
criteria.add(Restrictions.like("cust_name", "王%"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}

@Test
/**
* 统计查询
*/
public void demo5() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

Criteria criteria = session.createCriteria(Customer.class);
/**
* add    :普通的条件。where条件后面
* addorder   :排序
* setProjection :聚合函数和group by having
*/
Long count = (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();

transaction.commit();
}

@Test
/**
* 离线条件查询
*/
public void demo6() {
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.like("cust_name","王%"));
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}

transaction.commit();
}
}

两个配置文件,

hibernate.cfg.xml配置PG数据库的方言

<property name="hibernate.dialect">
  org.hibernate.spatial.dialect.postgis.PostgisDialect
</property>

根据给出的表填写hibernate映射文件。

参考:以城市为例:
实体类:

package cn.edu.chzu.xxxy.gisda;

import org.geolatte.geom.Point;

public class City {
private Integer id;
private String name;
private String province;
private Point<?> geom;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public City() {
}
public City(String name, String province, Point<?> geom) {
this.name=name;
this.province=province;
this.geom=geom;
}
public Point<?> getGeom() {
return geom;
}
public void setGeom(Point<?> geom) {
this.geom = geom;
}
@Override
public String toString() {
return "City [id=" + id + ", name=" + name + ", province=" + province + ", geom=" + geom.toString() + "]";
}

}

hibernate映射文件:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
<class name="cn.edu.chzu.xxxy.gisda.City" table="city" lazy="false">
  <id name="id" type="java.lang.Integer" column="id">
     <generator class="identity"/>
  </id>
  <property name="name" column="name"/>
  <property name="province" column="province"/> 
  <property name="geom" column="geom"/> 
</class>
</hibernate-mapping>

已知(河流)增加的方法,完成删除、修改、查询方法。

参考:
河流跟城市差不多,只是字段不一样,这里以城市为例,接上面的城市的实体类和配置文件。

package cn.edu.chzu.xxxy.gisda;
import java.util.List;
import org.geolatte.geom.Point;
import org.geolatte.geom.codec.Wkt;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class ManageCity {

	private static SessionFactory factory; 

	public static void main(String[] args) {
		try{
			factory = new Configuration().configure().buildSessionFactory();
        }catch (Throwable ex) { 
			System.err.println("Failed to create sessionFactory object." + ex);
	        throw new ExceptionInInitializerError(ex); 
		}
		ManageCity citymain=new ManageCity();
		Integer cityId1=citymain.addCity("chuzhou", "anhui",(Point<?>)Wkt.fromWkt("SRID=4326;Point(118 32)"));
		Integer cityId2=citymain.addCity("hefei", "anhui",(Point<?>)Wkt.fromWkt("SRID=4326;Point(117 31)"));
		Integer cityId3=citymain.addCity("fengyang", "anhui",(Point<?>)Wkt.fromWkt("SRID=4326;Point(117 33)"));
				 citymain.listCitys(); 
		//citymain.updateCity(cityId1,"jiangsu");
		//citymain.deleteCity(cityId3);
				 //citymain.listCitys();		 
	}
	
	public Integer addCity(String name, String province, Point<?> geom){
		Session session = factory.openSession();
		Transaction tx = null;
		Integer cityId=null;
		try{
			tx = session.beginTransaction();
			City city = new City(name, province, geom);
			/*city.toString();
	        Map mcity = new HashMap(); 
			mcity.put("name", city.getName());
			mcity.put("province", city.getProvince());
			mcity.put("geom", (Point<?>)city.getGeom());
			cityId = (Integer)session.save("cn.edu.chzu.xxxy.gisda.City",mcity);*/
				         session.save(city);        
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
            e.printStackTrace(); 
		}finally {
	         session.close(); 
		}
		return cityId;
	}
		 
	public void listCitys( ){
		Session session = factory.openSession();
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
	        List<City> citys = session.createQuery("FROM City").list(); 
			/*for (Iterator<?> iterator = 
				citys.iterator(); iterator.hasNext();){
	            Map mcity = (Map) iterator.next(); 
				City city=new City((String)mcity.get("name"), 					(String)mcity.get("province"), (Point<?>)mcity.get("geom"));
				System.out.println(city.toString());
			}*/
			for (City city : citys) {
				System.out.println(city);
			}
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
	        e.printStackTrace(); 
		}finally {
            session.close(); 
		}
	}
	public void updateCity(Integer cityID, String province ){
		Session session = factory.openSession();
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
	        City City = (City)session.get(City.class, cityID); 
			City.setProvince( province );
	        session.update(City); 
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
	        e.printStackTrace(); 
		}finally {
	         session.close(); 
		}
	}
	public void deleteCity(Integer cityID){
		Session session = factory.openSession();
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
	        City city = (City)session.get(City.class, cityID); 
	        session.delete(city); 
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
            e.printStackTrace(); 
		}finally {
            session.close(); 
		}
	}
}

jdbc读取db.properties(定义Env类)

参考:

Env.java
package top.jacktgq;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public final class Env extends Properties{
	public static Env instance;
	public static Env getInstance() {
		if(instance == null) {
		    makeInstance();
		}
		return instance;
	}
	private static synchronized void makeInstance() {
		if(instance == null) {
			instance = new Env();
		}
	}
	
	public Env() {
		InputStream in = getClass().getResourceAsStream("/db.properties");
		try {
			load(in);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("数据库配置文件不存在!");
		}
	}
}

jdbc数据库操作,需要调用Env.java

package top.jacktgq;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import org.postgresql.ds.PGPoolingDataSource;

public class JNDI_PostGisHelper {
	private Connection conn = null;
	//通过数据源获取数据库连接
	public static Connection getConnection() {
		PGPoolingDataSource ds = new PGPoolingDataSource();
		ds.setDataSourceName(Env.getInstance().getProperty("dsn"));
		ds.setServerName(Env.getInstance().getProperty("url"));
		ds.setPortNumber(Integer.parseInt(Env.getInstance().getProperty("port")));
		ds.setDatabaseName(Env.getInstance().getProperty("dbname"));
		ds.setUser(Env.getInstance().getProperty("uid"));
		ds.setPassword(Env.getInstance().getProperty("pwd"));
   	  ds.setMaxConnections(Integer.parseInt(Env.getInstance().getProperty("maxconn")));
		try {
			return ds.getConnection();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	public JNDI_PostGisHelper() {
		conn = getConnection();
	}
}

Spring框架:按照视频上看的。spring框架的配置文件,创建struts对象,配置常量。

配置常量:(在struts.xml中配置添加如下配置,由Spring来完成Action对象的创建)

<constant name="struts.objectFactory" value="spring"></constant>

权限的过滤,动作的拦截。(写一个完整的程序,总共四分)。
参考:
在这里插入图片描述

此处可以通过使用AspectJ完成spring的AOP操作,实现对权限的过滤。

1、编写切面类:

package top.jacktgq.rhs.Aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import top.jacktgq.rhs.domain.Rubbish_Source;
import top.jacktgq.rhs.utils.C3P0Utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * @Author CandyWall
 * @Date 2019/6/21--21:14
 * @Description 切面类
 */
public class MyAspect {
    public void checkPri() {
        System.out.println("权限校验==============");
    }
    //校验待插入的垃圾源(坐标)是否存在,如果存在就不允许后续的创建,如果不存在,则允许创建
    public void checkRubbish_source_ifExist(ProceedingJoinPoint pjp) throws SQLException {
        Object[] args = pjp.getArgs();
        //System.out.println(args[0]);
        //获取垃圾源对象参数
        Rubbish_Source rubbish_source = (Rubbish_Source) args[0];
        System.out.println(rubbish_source.getGeom().toString().substring(10));
        //查询数据库,校验坐标是否存在
        Connection conn = C3P0Utils.getDataSource().getConnection();
        //select * from rubbish_source where st_astext(geom)='MULTIPOINT(118.302132378747 32.276233780295)'
        String sql = "select * from rubbish_source where st_astext(geom)=?";
        PreparedStatement pstm = conn.prepareStatement(sql);
        pstm.setString(1,rubbish_source.getGeom().toString().substring(10));
        ResultSet rs = pstm.executeQuery();
        try {
            if (rs.next()) {
                pjp.proceed(args);
            } else {
                System.out.println("已存在该垃圾源坐标,添加垃圾源失败!");
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

2、在spring的applicationContext.xml中添加如下配置:

<aop:config>
<!-- 表达式配置哪些类的哪些方法需要增强 -->
<aop:pointcut id="pointcut1" expression="execution(* top.jacktgq.rhs.dao.impl.Rubbish_SourceDaoImpl.addRubbish_Source(..))"/>
<!-- 配置切面 -->
<aop:aspect ref="myAspect">
  <!--<aop:before method="checkRubbish_source_ifExist" pointcut-ref="pointcut1"/>-->
  <!-- 配置环绕通知可以在被增强的方法调用前获取其参数,然后查询数据库进行坐标的比对,从而完成校验 -->
  <aop:around method="checkRubbish_source_ifExist" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>

写几个空间分析的方法:postgis API,计算长度。

在这里插入图片描述
在这里插入图片描述 ## 第二大题 程序分析题:写Action接口,定义ActionMapping内部映射类。struts框架struts.xml配置文件
参考:

Action类:

package top.jacktgq.rhs.web.Action;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.struts2.ServletActionContext;
import org.geolatte.geom.MultiPoint;
import org.geolatte.geom.codec.Wkt;
import top.jacktgq.rhs.domain.PageBean;
import top.jacktgq.rhs.domain.Rubbish_Source;
import top.jacktgq.rhs.service.Rubbish_SourceService;
import top.jacktgq.rhs.service.impl.Rubbish_SourceServiceImpl;
import top.jacktgq.rhs.utils.AndroidMultiPointToGsonSerializer;
import top.jacktgq.rhs.utils.MultiPointToGsonSerializer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author CandyWall
 * @Date 2019/5/16--13:33
 * @Description 垃圾源的管理(空间点 的增删改查)
 */
public class ManageRubbish_Source extends ActionSupport implements ModelDriven<Rubbish_Source> {
    //注入Rubbish_sourceService
    private Rubbish_SourceService rubbish_sourceService;

    public void setRubbish_sourceService(Rubbish_SourceService rubbish_sourceService) {
        this.rubbish_sourceService = rubbish_sourceService;
    }

    //用于模型驱动的实体类
    private Rubbish_Source rubbish_source = new Rubbish_Source();

    public Rubbish_Source getRubbish_source() {
        return rubbish_source;
    }

    public void setRubbish_source(Rubbish_Source rubbish_source) {
        this.rubbish_source = rubbish_source;
    }

    //空间点对象不能直接通过模型驱动的方式添加到rubbish_source对象中,单独获取
    private String point_str;

    public void setPoint_str(String point_str) {
        this.point_str = point_str;
    }

    @Override
    public Rubbish_Source getModel() {
        return rubbish_source;
    }

    //分页获取所有的垃圾源信息
    public void getRubbish_Source() throws IOException {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        //System.out.println("调用成功!!!!");
        //获得当前页序号
        int currentPage = 1;
        if (request.getParameter("currentPage") != null) {
            currentPage = Integer.parseInt(request.getParameter("currentPage"));
        }
        //设置当前页显示的条数
        int currentCount = Integer.parseInt(request.getParameter("currentCount"));
        //通过获得封装分页信息的类来获得当前页的信息
        PageBean<Rubbish_Source> pageBean = rubbish_sourceService.getRubbish_SourceByPage(currentPage, currentCount);
        Map<String, Object> pageBeanMap = new HashMap<String, Object>();
        pageBeanMap.put("status", 200);
        pageBeanMap.put("hint", "连接成功");
        pageBeanMap.put("total", pageBean.getTotalCount());
        pageBeanMap.put("rows", pageBean.getList());
        //使用GsonBuilder对象创建gson对象,并注册空间 多点对象Json转换器。
        Gson gson = new GsonBuilder().registerTypeAdapter(MultiPoint.class, new MultiPointToGsonSerializer()).create();
        String rubbish_sourceListJson = gson.toJson(pageBeanMap);
        response.setCharacterEncoding("utf-8");
        response.setContentType("charset=utf-8;json/html");
        System.out.println(rubbish_sourceListJson);
        response.getWriter().write(rubbish_sourceListJson);
    }

    //添加一条垃圾源信息
    public void addRubbish_source() throws IOException {
        HttpServletResponse response = ServletActionContext.getResponse();
        Boolean ifSucceed = true;
        rubbish_source.setGeom((MultiPoint<?>) Wkt.fromWkt(point_str));
        rubbish_sourceService.addRubbish_Source(rubbish_source);
        response.getWriter().write("{\"ifSucceed\":" + ifSucceed + "}");    //把保存成功的结果返回给前台页面
    }

    //修改垃圾源信息回显,先根据获取到的Id号,查询对应的垃圾源信息,并传递给修改回显页面
    public String update_echo() {
        //默认情况下,Action会被压入值栈,所以Action中的属性也就在值栈中。
        rubbish_source = rubbish_sourceService.getRubbish_sourceById(rubbish_source.getId());
        //Rubbish_Source rubbish_source_echo = rubbish_sourceService.getRubbish_sourceById(rubbish_source.getId());
        //将值存储到值栈中
        //ActionContext.getContext().getValueStack().set("rubbish_source",rubbish_source_echo);
        return "update_echo";
    }

    //根据垃圾源编号修改垃圾源信息
    public void updateRubbish_source() throws IOException {
        HttpServletResponse response = ServletActionContext.getResponse();
        rubbish_source.setGeom((MultiPoint<?>) Wkt.fromWkt(point_str));
        Boolean ifSucceed = true;
        rubbish_sourceService.updateRubbish_source(rubbish_source);
        response.getWriter().write("{\"ifSucceed\":" + ifSucceed + "}");    //把保存成功的结果返回给前台页面
    }

    //根据垃圾源Id删除对应的垃圾源信息
    public void deleteById() throws IOException {
        System.out.println(rubbish_source);
        HttpServletResponse response = ServletActionContext.getResponse();
        Boolean ifSucceed = true;
        rubbish_sourceService.deleteById(rubbish_source.getId());
        response.getWriter().write("{\"ifSucceed\":" + ifSucceed + "}");
    }
}

struts.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.objectFactory" value="spring"></constant>
<package name="first_gridman" extends="struts-default" namespace="/">
    <action name="getGeomFromPG_*" class="getGeomFromPG" method="{1}">
    </action>
    <action name="manageGridmen_*" class="manageGridmen" method="{1}">
        <result name="fg_index" type="redirect">/first_gridman/fg_index.jsp</result>
        <result name="sg_index" type="redirect">/second_gridman/sg_index.jsp</result>
        <result name="login" type="dispatcher">/</result>
        <result name="success" type="redirect">/first_gridman/showAllSecondGridmeninfo.jsp</result>
        <result name="input" type="redirect">/</result>
    </action>
    <action name="rs_*" class="manageRubbish_source" method="{1}">
        <result name="update_echo" type="dispatcher">/first_gridman/updateRubbish_Source.jsp</result>
        <result name="success" type="dispatcher">/first_gridman/showAllRubbish_SourceInfo.jsp</result>
    </action>
    <action name="chzu_line_*" class="manageChzu_Line" method="{1}">
        <result name="update_echo" type="dispatcher">/first_gridman/updateChzu_Line.jsp</result>
        <result name="success" type="dispatcher">/first_gridman/showChzu_LineInfo.jsp</result>
        <result name="input" type="dispatcher">/first_gridman/showChzu_LineInfo.jsp</result>
    </action>
    <action name="chzu_mian_*" class="manageChzu_Mian" method="{1}">
        <result name="update_echo" type="dispatcher">/first_gridman/updateChzu_Mian.jsp</result>
        <result name="success" type="dispatcher">/first_gridman/showChzu_MianInfo.jsp</result>
        <result name="input" type="dispatcher">/first_gridman/showChzu_MianInfo.jsp</result>
    </action>
</package>
</struts>

最后一题18分:综合应用题,三套卷子两个专业大同小异,从上到下,7到8个小问题。三大框架的整合,完整的内容,填空。SSH,登录、注册功能。Action、Service、Dao层,从配置文件到代码。

参考:

12、SSH框架整合应用开发“网上书店”的注册用户功能模块,在各题横线上补全代码。

12.1 Spring整合Struts2框架。填写web.xml文件的元素下的Spring监听器的代码:

<listener>
    <listener-class>
    	org.springframework.web.context.ContextLoaderListener 
    </listener-class>
</listener>

12.2 Spring配置文件applicationContext.xml,请补全其配置信息。

<bean id=”baseDAO” class=”  cn.edu.zjut.dao.BaseHibernateDAO  “>
 	<property name=”sessionFactory” ref=”  sessionFactory   ”/>
</bean>
<bean id=”userAction” class”  cn.edu.zjut.action.UserAction   ” scope=”  prototype   ”>
<property name=”userService” ref=”_userService_”/>
</bean>
<bean id=”sessionFactory” Class=”org.springframework.orm.hibernate5.LocalSessionFactoryBean”>
	<property name=”dataSource” ref=”dataSource”/>
	<property name=”hibernateProperties”>
		<props>
		<prop key=”hibernate.dialect”>__org.hibernate.dialect.MySQLdialect__</prop>
		</props>
	</property>
	<property name=”mappingResouces”>
		<list>
		<value>_ cn.edu.zjut.po.Customer.hbm.xml__</value>
		</list>
	</property>
</bean>

12.3 Struts2框架的核心配置文件struts.xml中的action元素的属性class,其值为:class=” userAction “

12.4 UserAction.java的register方法的实现代码:

public String execute(){
   userService.register(loginUser);  
   return  “success”;  
}

12.5 UserService.java的register方法的实现代码:

@Override
public void register(Customer cust){
   customerDAO.save(cust); 
}
12.6 CustomerDAO.java的save方法的实现代码:
 public void save (Customer transientInstance){
    Transaction tran=null;
    Session session=null;
    try{
		session=  getSession()  ;
		tran=session.  beginTransaction()  ;
	    session.save(transientInstance)  ;
	    tran.commit();
	}catch(RuntimeException re){
	 	if(tran!=null)  tran.rollback()  ;
	   	throw re;
	}finally{
		session.close();
	}
}

12.7 regSuccess.jsp的代码,补齐缺失的Struts标签:

<%@page language=”java” contentType=”text/html; charset=GB18030” pageEncoding=” GB18030”%>
<%@taglib   prefix=”s” uri=”/struts-tags”  %>
<!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=GB18030”>
<s:property value=”  loginUser.name   ”/><!—用户的name属性-->
<s:if test=”loginUser.sex”><s:text name=”先生,”/>  </s:if> 
<s:else>   <s:text name=”女士,”/></s:else>

在这里插入图片描述

栅格文件和矢量文件读取:

参考:

package org.geotools.tutorial.raster;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Parameter;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.Hints;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.map.FeatureLayer;
import org.geotools.map.GridReaderLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.map.StyleLayer;
import org.geotools.styling.ChannelSelection;
import org.geotools.styling.ContrastEnhancement;
import org.geotools.styling.RasterSymbolizer;
import org.geotools.styling.SLD;
import org.geotools.styling.SelectedChannelType;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.action.SafeAction;
import org.geotools.swing.data.JParameterListWizard;
import org.geotools.swing.wizard.JWizard;
import org.geotools.util.KVP;
import org.opengis.filter.FilterFactory2;
import org.opengis.style.ContrastMethod;

public class ImageLab {

    private StyleFactory sf = CommonFactoryFinder.getStyleFactory();
    private FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();

    private JMapFrame frame;
    private GridCoverage2DReader reader;

    public static void main(String[] args) throws Exception {
        ImageLab me = new ImageLab();
        me.getLayersAndDisplay();
    }
    /**
     * Prompts the user for a GeoTIFF file and a Shapefile and passes them to the displayLayers
     * method
     */
    private void getLayersAndDisplay() throws Exception {
        List<Parameter<?>> list = new ArrayList<>();
        list.add(
                new Parameter<>(
                        "image",
                        File.class,
                        "Image",
                        "GeoTiff or World+Image to display as basemap",
                        new KVP(Parameter.EXT, "tif", Parameter.EXT, "jpg")));
        list.add(
                new Parameter<>(
                        "shape",
                        File.class,
                        "Shapefile",
                        "Shapefile contents to display",
                        new KVP(Parameter.EXT, "shp")));

        JParameterListWizard wizard =
                new JParameterListWizard("Image Lab", "Fill in the following layers", list);
        int finish = wizard.showModalDialog();

        if (finish != JWizard.FINISH) {
            System.exit(0);
        }
        File imageFile = (File) wizard.getConnectionParameters().get("image");
        File shapeFile = (File) wizard.getConnectionParameters().get("shape");
        displayLayers(imageFile, shapeFile);
        
    }
    /**
     * Displays a GeoTIFF file overlaid with a Shapefile
     *
     * @param rasterFile the GeoTIFF file
     * @param shpFile the Shapefile
     */
    private void displayLayers(File rasterFile, File shpFile) throws Exception {
        AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
        // this is a bit hacky but does make more geotiffs work
        Hints hints = new Hints();
        if (format instanceof GeoTiffFormat) {
            hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
        }
        reader = format.getReader(rasterFile, hints);

        // Initially display the raster in greyscale using the
        // data from the first image band
        Style rasterStyle = createGreyscaleStyle(1);

        // Connect to the shapefile
        FileDataStore dataStore = FileDataStoreFinder.getDataStore(shpFile);
        SimpleFeatureSource shapefileSource = dataStore.getFeatureSource();

        // Create a basic style with yellow lines and no fill
        Style shpStyle = SLD.createPolygonStyle(Color.YELLOW, null, 0.0f);

        // Set up a MapContent with the two layers
        final MapContent map = new MapContent();
        map.setTitle("ImageLab");

        Layer rasterLayer = new GridReaderLayer(reader, rasterStyle);
        map.addLayer(rasterLayer);

        Layer shpLayer = new FeatureLayer(shapefileSource, shpStyle);
        map.addLayer(shpLayer);

        // Create a JMapFrame with a menu to choose the display style for the
        frame = new JMapFrame(map);
        frame.setSize(800, 600);
        frame.enableStatusBar(true);
        // frame.enableTool(JMapFrame.Tool.ZOOM, JMapFrame.Tool.PAN, JMapFrame.Tool.RESET);
        frame.enableToolBar(true);

        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        JMenu menu = new JMenu("Raster");
        menuBar.add(menu);

        menu.add(
                new SafeAction("Grayscale display") {
                    public void action(ActionEvent e) throws Throwable {
                        Style style = createGreyscaleStyle();
                        if (style != null) {
                            ((StyleLayer) map.layers().get(0)).setStyle(style);
                            frame.repaint();
                        }
                    }
                });

        menu.add(
                new SafeAction("RGB display") {
                    public void action(ActionEvent e) throws Throwable {
                        Style style = createRGBStyle();
                        if (style != null) {
                            ((StyleLayer) map.layers().get(0)).setStyle(style);
                            frame.repaint();
                        }
                    }
                });
        // Finally display the map frame.
        // When it is closed the app will exit.
        frame.setVisible(true);
    }
    private Style createGreyscaleStyle() {
        GridCoverage2D cov = null;
        try {
            cov = reader.read(null);
        } catch (IOException giveUp) {
            throw new RuntimeException(giveUp);
        }
        int numBands = cov.getNumSampleDimensions();
        Integer[] bandNumbers = new Integer[numBands];
        for (int i = 0; i < numBands; i++) {
            bandNumbers[i] = i + 1;
        }
        Object selection =
                JOptionPane.showInputDialog(
                        frame,
                        "Band to use for greyscale display",
                        "Select an image band",
                        JOptionPane.QUESTION_MESSAGE,
                        null,
                        bandNumbers,
                        1);
        if (selection != null) {
            int band = ((Number) selection).intValue();
            return createGreyscaleStyle(band);
        }
        return null;
    }

    /**
     * Create a Style to display the specified band of the GeoTIFF image as a greyscale layer.
     *
     * <p>This method is a helper for createGreyScale() and is also called directly by the
     * displayLayers() method when the application first starts.
     *
     * @param band the image band to use for the greyscale display
     * @return a new Style instance to render the image in greyscale
     */
    private Style createGreyscaleStyle(int band) {
        ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NORMALIZE);
        SelectedChannelType sct = sf.createSelectedChannelType(String.valueOf(band), ce);

        RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
        ChannelSelection sel = sf.channelSelection(sct);
        sym.setChannelSelection(sel);

        return SLD.wrapSymbolizers(sym);
    }
    /**
     * This method examines the names of the sample dimensions in the provided coverage looking for
     * "red...", "green..." and "blue..." (case insensitive match). If these names are not found it
     * uses bands 1, 2, and 3 for the red, green and blue channels. It then sets up a raster
     * symbolizer and returns this wrapped in a Style.
     *
     * @return a new Style object containing a raster symbolizer set up for RGB image
     */
    private Style createRGBStyle() {
        GridCoverage2D cov = null;
        try {
            cov = reader.read(null);
        } catch (IOException giveUp) {
            throw new RuntimeException(giveUp);
        }
        // We need at least three bands to create an RGB style
        int numBands = cov.getNumSampleDimensions();
        if (numBands < 3) {
            return null;
        }
        // Get the names of the bands
        String[] sampleDimensionNames = new String[numBands];
        for (int i = 0; i < numBands; i++) {
            GridSampleDimension dim = cov.getSampleDimension(i);
            sampleDimensionNames[i] = dim.getDescription().toString();
        }
        final int RED = 0, GREEN = 1, BLUE = 2;
        int[] channelNum = {-1, -1, -1};
        // We examine the band names looking for "red...", "green...", "blue...".
        // Note that the channel numbers we record are indexed from 1, not 0.
        for (int i = 0; i < numBands; i++) {
            String name = sampleDimensionNames[i].toLowerCase();
            if (name != null) {
                if (name.matches("red.*")) {
                    channelNum[RED] = i + 1;
                } else if (name.matches("green.*")) {
                    channelNum[GREEN] = i + 1;
                } else if (name.matches("blue.*")) {
                    channelNum[BLUE] = i + 1;
                }
            }
        }
        // If we didn't find named bands "red...", "green...", "blue..."
        // we fall back to using the first three bands in order
        if (channelNum[RED] < 0 || channelNum[GREEN] < 0 || channelNum[BLUE] < 0) {
            channelNum[RED] = 1;
            channelNum[GREEN] = 2;
            channelNum[BLUE] = 3;
        }
        // Now we create a RasterSymbolizer using the selected channels
        SelectedChannelType[] sct = new SelectedChannelType[cov.getNumSampleDimensions()];
        ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NORMALIZE);
        for (int i = 0; i < 3; i++) {
            sct[i] = sf.createSelectedChannelType(String.valueOf(channelNum[i]), ce);
        }
        RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
        ChannelSelection sel = sf.channelSelection(sct[RED], sct[GREEN], sct[BLUE]);
        sym.setChannelSelection(sel);

        return SLD.wrapSymbolizers(sym);
    }
}

核心代码如下:

AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
Hints hints = new Hints();
if (format instanceof GeoTiffFormat) {
      hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
}
reader = format.getReader(rasterFile, hints);
Style rasterStyle = createGreyscaleStyle(1);
FileDataStore dataStore = FileDataStoreFinder.getDataStore(shpFile);
SimpleFeatureSource shapefileSource = dataStore.getFeatureSource();
Style shpStyle = SLD.createPolygonStyle(Color.YELLOW, null, 0.0f);
final MapContent map = new MapContent();
map.setTitle("ImageLab");
Layer rasterLayer = new GridReaderLayer(reader, rasterStyle);
map.addLayer(rasterLayer);
Layer shpLayer = new FeatureLayer(shapefileSource, shpStyle);
map.addLayer(shpLayer);

Struts2框架执行流程

1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5 ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper