COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

58
COMP 321 Week 13

Transcript of COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Page 1: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

COMP 321

Week 13

Page 2: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Overview

Filters

Scaling and Remote Models

MVC and Struts

Page 3: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Problem

We have a working web application with many Servlets. Now we decide we need to keep track of how many times each users accesses each Servlet

How can we do this without modifying each Servlet?

Page 4: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Filters

Can intercept requests before they are passed to the servlet, and intercept responses before they are returned to the client

Can be chained together

Page 5: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Filters

Request filters can: Perform security checks Reformat request headers or bodies Audit or log requests

Response filters can: Compress the response stream Append to or alter the response stream Create an entirely different response

Difference between a request and response filter is only the programmers intention – there is no actual difference in implementation!

Page 6: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Logging Requestspublic class BeerRequestFilter implements Filter { private FilterConfig fc;

public void init(FilterConfig config) throws ServletException { this.fc = config; }

public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {

HttpServletRequest httpReq = (HttpServletRequest) req; String name = httpReq.getRemoteUser();

if (name != null) { fc.getServletContext().log("User " + name + " is updating"); }

chain.doFilter(req, resp); }}

Page 7: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Declaring and Ordering Filters<!-- In DD --><filter> <filter-name>BeerRequest</filter-name> <filter-class>com.example.web.BeerRequestFilter</filter-class> <init-param> <param-name>LogFileName</param-name> <param-value>UserLog.txt</param-value> </init-param></filter>

<filter-mapping> <filter-name>BeerRequest</filter-name> <url-pattern>*.do</url-pattern></filter-mapping><filter-mapping> <filter-name>BeerRequest</filter-name> <servlet-name>AdviceServlet</servlet-name></filter-mapping>

Page 8: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/HopsReport.do

Page 9: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/HopsReport.do Filters: 1, 5

Page 10: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/HopsList.do

Page 11: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/HopsList.do Filters: 1, 5, 2

Page 12: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/Modify/ModRecipes.do

Page 13: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/Modify/ModRecipes.do Filters: 1, 5, 4

Page 14: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /HopsList.do

Page 15: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /HopsList.do Filters: 5

Page 16: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/Add/AddRecipes.do

Page 17: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Sharpen Your Pencil<filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/Recipes/*</url-pattern></filter-mapping><!-- Mapping ... --> <filter-name>Filter2</filter-name> <servlet-name>/Recipes/HopsList.do</servlet-name>

<filter-name>Filter3</filter-name> <url-pattern>/Recipes/Add/*</url-pattern>

<filter-name>Filter4</filter-name> <servlet-name>/Recipes/Modify/ModRecipes.do</servlet-name>

<filter-name>Filter5</filter-name> <url-pattern>/*</url-pattern>

Request: /Recipes/Add/AddRecipes.do Filters: 1, 3, 5

Page 18: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filters

What if we want to compress the response? How can we do this?

Will this work?

public void doFilter(…) { // request handling

chain.doFilter(request, response);

// do compression here}

Page 19: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filters

By the time the filter gets the response back, the servlet has already written to the output stream in the response, and the data has been sent back to the browser

We need to intercept this data somehow

Page 20: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filterspublic class CompressionResponseWrapper extends HttpServletResponseWrapper

{ public ServletOutputStream getOutputStream() throws IOException { return new GZIPOutputStream(getResponse().getOutputStream()); }}

public class MyCompressionFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {

CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response);

chain.doFilter(request, wrappedResp);

//Some compression logic here?}

Page 21: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filterspublic class CompressionResponseWrapper extends HttpServletResponseWrapper

{ public ServletOutputStream getOutputStream() throws IOException { return new GZIPOutputStream(getResponse().getOutputStream()); }}

public class MyCompressionFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {

CompressionResponseWrapper wrappedResp = new CompressionResponseWrapper(response);

chain.doFilter(request, wrappedResp); //Some compression logic here?}

Problems: getOutputStream() returns a new stream each time it's called GZIPOutputStream is not a ServletOutputStream GZIPOutputStream.finish() must be called

Page 22: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filterspublic class MyCompressionFilter implements Filter { private FilterConfig cfg; private ServletContext ctx;

@Override public void init(FilterConfig cfg) throws ServletException { this.cfg = cfg; ctx = cfg.getServletContext(); ctx.log(cfg.getFilterName() + " initialized."); }

@Override public void destroy() { cfg = null; ctx = null; }

Page 23: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filters public void doFilter(ServletRequest req, ServletResponse resp,

FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp;

String validEncodings = request.getHeader("Accept-Encoding"); if(validEncodings.indexOf("gzip") > -1) { CompressionResponseWrapper wrappedResp =

new CompressionResponseWrapper(response); wrappedResp.setHeader("Context-Encoding", "gzip"); chain.doFilter(request, wrappedResp); wrappedResp.finishGZIP(); ctx.log(cfg.getFilterName() + ": finished the request."); } else { ctx.log(cfg.getFilterName() + ": no encoding performed."); chain.doFilter(request, response); } }}

Page 24: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filterspublic class CompressionResponseWrapper extends HttpServletResponseWrapper

{ private GZIPServletOutputStream gzos = null; private PrintWriter pw = null; private Object streamUsed = null;

public CompressionResponseWrapper(HttpServletResponse response) { super(response); }

public void finishGZIP() throws IOException { gzos.finish(); }

Page 25: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filters@Overridepublic ServletOutputStream getOutputStream() throws IOException { if(streamUsed != null && streamUsed != gzos) throw new IllegalStateException();

if(gzos == null) { gzos = new GZIPServletOutputStream(getResponse().getOutputStream()); streamUsed = gzos; }

return gzos;}

Page 26: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filters@Overridepublic PrintWriter getWriter() throws IOException { if(streamUsed != null && streamUsed != pw) throw new IllegalStateException();

if(pw == null) { gzos = new GZIPServletOutputStream(getResponse().getOutputStream()); OutputStreamWriter osw =

new OutputStreamWriter(gzos, getResponse().getCharacterEncoding());

pw = new PrintWriter(osw); streamUsed = pw; }

return pw;}

Page 27: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Response Filterspublic class GZIPServletOutputStream extends ServletOutputStream {

GZIPOutputStream os;

public GZIPServletOutputStream(ServletOutputStream sos) throws IOException {

this.os = new GZIPOutputStream(sos);}

public void finish() throws IOException{

os.finish();}

public void write(int param) throws IOException {os.write(param);

}}

Page 28: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Horizontal Scaling

Enterprise web applications can get hundreds of thousands of hits per day

To handle this volume, work must be distributed across many machines

Hardware is normally configured in tiers, and increased load can be handled by adding machines to a tier

Page 29: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Horizontal Scaling

Page 30: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Two Classes of Requirements

Functional: Application operates correctly

Non-Functional: Performance Modularity Flexibility Maintainability Extensibility

How do we make sure we can handle these?

Page 31: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

To Meet Non-functional Requirements

Code to interfaces

Separation of Concerns

Cohesion

Hiding Complexity

Loose Coupling

Increase Declarative Control

Page 32: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Improving the Beer App

Current Implementation:1. Web request received, Controller calls

ManageCustomer service, and gets a Customer bean back

2. Controller adds Customer bean to request object

3. Controller forwards to the View JSP

4. JSP uses EL to get properties and generate page

Page 33: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Local Model

Page 34: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Question

How can we put the components on different servers and have them still talk to each other?

Page 35: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Solution

JNDI – supplies centralized network service for finding things

RMI – allows method calls to objects on different machines

Page 36: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

JNDI

Java Naming and Directory Interface

Maintains a registry of objects

Allows object lookup via locator string

Allows objects to be relocated transparently - clients don’t need to know

Page 37: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

RMI

Remote method invocation

Allows methods on an object to be called from a client on a different machine

Moving parameters and return values across the network requires only that they be Serializable

Page 38: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

RMI (cont’d) – Server Side

1. Create a remote interface

2. Create implementation

3. Generate stub and skeleton

4. Register objects

Page 39: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

RMI (cont’d) – Client Side

1. Look up object

2. Call methods normally

Page 40: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Design Issues

We would like to use the same controller whether the model is local or remote– How do we handle RMI lookups?– How do we handle remote exceptions?

Page 41: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Solution

We need a go-between to handle these things - the Business Delegate

Page 42: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Business Delegate

Looks like a model object - implements same interface

Connects to the real model object via RMI

Delegates all calls to the real model object (possibly across the network)

Page 43: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Service Locator

Helps avoid duplicating code in Business Delegates

Responsible for locating objects via JNDI, and returning stubs to Business Delegates

Page 44: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Local Model (Take #2)

Page 45: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Remote Model

1. Register services with JNDI

2. Use Business Delegate and Service Locator to get ManageCustomer stub from JNDI

3. Use Business Delegate and stub to get Customer bean (another stub), and return to Controller

4. Add Customer stub to request

5. Forward to View JSP

6. View JSP uses EL to get properties from Customer bean, unaware that it isn’t the actual bean

Page 46: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Remote Model

Page 47: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Remote Model - Downsides

Fine-grained calls to get properties cause a large performance hit

JSP shouldn’t have to handle remote exceptions

How can we solve these problems?

Page 48: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Solution – Transfer Objects!

Remember Transfer Object? Serializable beans that can be returned

across remote interfaces Prevent simple get/set calls from having to

traverse network boundaries See Week 5 slides

Page 49: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Return to MVC

Where we left off… Each view was a JSP Data was held in model classes Each URL had its own controller, and there

was a lot of duplicated code between them

Page 50: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Controllerprotected void doPost(HttpServletRequest request, HttpServletResponse

response)throws ServletException, IOException {

// Dealing with request... String c = request.getParameter("startDate"); // Do data conversion on date parameter // Validate that date is in range // If any errors happen, forward to hard-coded retry JSP

// Dealing with model... // Invoke hard-coded model components // add model results to request object

// Dealing with view... // dispatch to hard-coded view JSP}

Page 51: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Controllerprotected void doPost(HttpServletRequest request, HttpServletResponse

response)throws ServletException, IOException {

// Dealing with request... String c = request.getParameter("startDate"); // Do data conversion on date parameter // Validate that date is in range // If any errors happen, forward to hard-coded retry JSP

// Dealing with model... // Invoke hard-coded model components // add model results to request object

// Dealing with view... // dispatch to hard-coded view JSP}

The controller is tightly coupled to the model and views, and we also have issues with duplicate code.How can we split this up?

Page 52: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Controller

1. Handle request – give this task to a separate validation component

2. Invoke model – declaratively list models that should be used

3. Dispatch to the view – declaratively define views to be used based on controller results

Page 53: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Introducing Struts

1. Controller receives request, looks up Form Bean, sets attributes, and calls validate()

2. Controller looks up Action Object, calls execute()

3. Using result of action, Controller forwards request to correct view

Page 54: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Struts (cont’d)

Page 55: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Moving to Strutspublic class BeerSelectForm extends ActionForm { private String color; public void setColor(String color) { this.color = color; } public String getColor() { return color; }

private static final String VALID_COLORS = "amber,dark,light,brown"; public ActionErrors validate(ActionMapping mapping,

HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if(VALID_COLORS.indexOf(color) == -1) { errors.add("color", new ActionMessage("error.colorField.notValid"); }

return errors; }}

Page 56: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Moving to Strutspublic class BeerSelectAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form,

HttpServletRequest request, HttpServletResponse response) { BeerSelectForm myForm = (BeerSelectForm)form;

//Process the business logic BeerExpert be = new BeerExpert(); List result = be.getBrands(myForm.getColor());

//Forward to the results view request.setAttribute("styles", result); return mapping.findForward("show_results"); }}

Page 57: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Moving to Struts<struts-config> <form-beans> <form-bean name="selectBeerForm"

type="com.example.web.BeerSelectForm"/> </form-beans>

<action-mappings> <action path="/SelectBeer" type="com.example.web.BeerSelectAction" name="selectBeerForm" scope="request" validate="true" input="/form.jsp"> <forward name="show_results" path="/result.jsp" /> </action> </action-mappings>

...</struts-config>

Page 58: COMP 321 Week 13. Overview Filters Scaling and Remote Models MVC and Struts.

Progress Check

Due this week– Lab 12-1 Wrapper Design Problem

Due next week– Lab 10-1 JSP User Interfaces– Lab 13-1 Web Frameworks