Request bean and KvpRequestReader
A request bean is basically a java object carrying all parsed parameter key-value pairs (as well as their getter and setter methods) of a specific service operation’s request. For example GeoServer’s WMS service has GetMap operation so which uses GetMapRequest (org.vfny.geoserver.wms.requests.GetMapRequest) bean, and same idea GetCapabilities operation has WMSCapabilitiesRequest bean. Now for “ags-ows” service, since “export” is the only operation declared in ArcGISServerOWSService, I will create one request bean class and call it AgsOwsExportRequest (below is a sample implementation that omits getters and setters):
you probably notice that each request bean parameter represents one request parameter of “ags-ows” service, and the type of the parameter matches the binding class of parameter’s kvp parser. (e.g. AgsOwsKvpLayersParser binds to List<LayerInfo>, AgsOwsKvpSizeParser binds to AgsOwsExportSize class etc.)1: public class AgsOwsExportRequest {2:3: private LayerInfo[] layers;
4: private Envelope bbox;
5: private AgsOwsExportSize size;
6: private CoordinateReferenceSystem imageSR;
7: private CoordinateReferenceSystem bboxSR;
8: private boolean transparent;9: private Color bgColor = Color.WHITE;
10:11: public AgsOwsExportRequest() {}
12: /*
13: * omitted getter and setter methods14: * you need to add getter and setter in your own code15: */16: }
Usually an OWS service’s operation logic takes its own request bean as input parameter (that’s why you saw AgsOwsExportRequest in previous post which I didn’t explain much then). Before the dispatcher redirects request the a service operation logic for further processing, it will create an instance of appropriate type of request bean and pass it in, and it’s actually a KvpRequestReader subclass’s job to create such request bean and populate it with parsed parameter objects from kvp parsers. So I created AgsOwsExportRequestKvpReader as below, which extends KvpRequestReader:
To extend KvpRequestReader, you basically override its createRequest() and read() method, and optionally set attribute “filter”.1: public class AgsOwsExportRequestKvpReader extends KvpRequestReader {2:3:4: public AgsOwsExportRequestKvpReader() {
5: super(AgsOwsExportRequest.class);6: }7:8: @Override9: public Object createRequest() throws Exception {10: AgsOwsExportRequest requestBean = new AgsOwsExportRequest();
11: return requestBean;
12: }13:14: @Override15: public Object read(Object request, Map kvp, Map rawKvp) throws Exception {16: AgsOwsExportRequest exportRequest = (AgsOwsExportRequest)super.read(request, kvp, rawKvp);
17: /*
18: * do any specific setting for AgsOwsExportRequest request bean instance -19: * - based on kvp and rawKvp20: */21: // TODO: here shall I set default value for certain parameters -
22: // - if they are missing from kvp?
23: return exportRequest;
24: }25: }
- createRequest() creates and returns a new instance of appropriate request bean object. Default creatRequest() does that by creating the new instance reflectively using KvpRequestReader.requestBean class (you set that class in constructor), but if you need to set extra attribute of request bean object then you should probably override it.
- read() is usually called in ows dispather, and it takes a request bean instance created by createReques() as well as kvp (java.util.Map) parsed by KvpParsers and unparsed raw kvp (java.util.Map), and it is suppose to loop through each key-value pair of parsed kvp map and set the applicable value in request bean instance if there is a setter defined for the key.
- “filter” is an optional attribute (through setFilter(Set<String> filter)) you can set so that certain keys in kvp can be filtered out without setting the its value to request bean instance.
Now it’s time to validate what I’ve added in “ags-ows” service project in this post so far. Restart GeoServer in debug mode, and set a break point in org.geoserver.ows.Dispatcher’s parseRequestKvp method (see highlighted line below), and send a “ags-ows” service request:1: <bean id="agsOwsExportKvpRequestReader"2: class="org.geoserver.ows.argisserver.kvp.AgsOwsExportRequestKvpReader">3: </bean>
http://localhost:8080/geoserver/ows/agsows?service=agsows&request=export&version=1.0.0&bbox=-124.731,24.956,-66.97,49.372&transparent=true&size=512,384&bboxSR=4326&imageSR=4326&layers=show:states
when it stops at the break point, check if variable “requestBean” is of class AgsOwsExportRequest, and also check if those attributes of AgsOwsExportRequest (e.g. “layers”, “bbox”, “imageSR” etc.) are populated with correct type of object values from kvp parsers. If so, it means AgsOwsExportRequest and AgsOwsExportRequestKvpReader are working as expected.1: Object parseRequestKVP(Class type, Request request)2: throws Exception {
3: KvpRequestReader kvpReader = findKvpRequestReader(type);4:5: if (kvpReader != null) {6: //check for http request awareness
7: if (kvpReader instanceof HttpServletRequestAware) {8: ((HttpServletRequestAware) kvpReader).setHttpRequest(request.httpRequest);9: }10:11: Object requestBean = kvpReader.createRequest();12:13: if (requestBean != null) {14: requestBean = kvpReader.read(requestBean, request.kvp, request.rawKvp);15: }16:17: return requestBean;
18: }19:20: return null;21: }
By now enough logics and functions have been added into “ags-ows” service to enable it to parse the request from client, in next post of this series, I will discuss more on the whole picture of how an ows request is processed by GeoServer OWS dispatcher, which is also a good half-way summary of what I've done so far.
No comments:
Post a Comment