参考:
根据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设计模式原理,解析三者之间调用关系。模型封装应用程序状态、响应状态查询、应用程序功能、通知视图改变;视图解释模型、模型更新请求、发送用户输入给控制器、允许控制器选择视图;控制器定义应用程序行为、用户动作映射成模型更新、选择响应的视图。
2.1控制器与模型间的方法调用是:状态改变。
2.2模型与视图间的方法调用和事件分别是:状态查询、通知改变
2.3视图与控制器间的方法调用和事件分别是:视图选择、用户请求
struts框架执行顺序(视频里面有):
参考:
根据Struts2框架及其工作原理,解析其工作流程。
①ActionProxy创建一个ActionInvocation实例。
②客户端浏览器发送请求,客户端初始化一个指向servlet容器(如Tomcat);
③接着核心控制器FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决
④⑤⑥⑦⑧⑨
②⑥③⑤④①⑨⑦⑧
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();
参考:
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 list = session.createQuery("from Customer").list();
//List 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 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
//查询多个属性,但是我想封装到对象中
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
参考:
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();
}
}
org.hibernate.spatial.dialect.postgis.PostgisDialect
参考:以城市为例:
实体类:
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() + "]";
}
}
参考:
河流跟城市差不多,只是字段不一样,这里以城市为例,接上面的城市的实体类和配置文件。
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();
}
}
}
参考:
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("数据库配置文件不存在!");
}
}
}
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();
}
}
配置常量:(在struts.xml中配置添加如下配置,由Spring来完成Action对象的创建)
权限的过滤,动作的拦截。(写一个完整的程序,总共四分)。
参考:
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();
}
}
}
## 第二大题 程序分析题:写Action接口,定义ActionMapping内部映射类。struts框架struts.xml配置文件
参考:
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 + "}");
}
}
/first_gridman/fg_index.jsp
/second_gridman/sg_index.jsp
/
/first_gridman/showAllSecondGridmeninfo.jsp
/
/first_gridman/updateRubbish_Source.jsp
/first_gridman/showAllRubbish_SourceInfo.jsp
/first_gridman/updateChzu_Line.jsp
/first_gridman/showChzu_LineInfo.jsp
/first_gridman/showChzu_LineInfo.jsp
/first_gridman/updateChzu_Mian.jsp
/first_gridman/showChzu_MianInfo.jsp
/first_gridman/showChzu_MianInfo.jsp
参考:
org.springframework.web.context.ContextLoaderListener
__org.hibernate.dialect.MySQLdialect__
_ cn.edu.zjut.po.Customer.hbm.xml__
public String execute(){
userService.register(loginUser);
return “success”;
}
@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” %>
参考:
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.
*
* 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);
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