Preparation time
less than 30 mins
Cooking time
10 to 30 mins
Serves
Serves 1
To make the saltfish fritters, in a medium bowl, start by adding the flour, add in the egg and whisk. Then add in the milk (add a little more if required). Season with salt and freshly ground black pepper.
In a medium sized saucepan, add the oil and make sure it's very hot. (CAUTION: Hot oil can be very dangerous. Do not leave unattended.)
Coat the fish in the batter and deep-fry until it is golden, for roughly 2-3 minutes.
Drain on kitchen paper.
To make the chips, preheat the oven to 200C/400F/Gas 6.
Cut the potato into thin matchsticks and place on a baking tray.
Sprinkle with oil and paprika and season with salt and freshly ground black pepper.
Place into the preheated oven for 15 minutes until golden and crisp.
To make the tomato relish, mix in a small bowl the tomatoes with the olive oil, the lime juice, the fresh herbs and the chilli flakes. Leave to stand for five minutes.
To serve, place the tomato relish at the bottom of the dish. Place the potato matchsticks and the fish on top and serve.


{% extends 'base.html' %} {% block title %} How to Read {% endblock %} {% block style %} body { text-align: justify; } origin { color: #007F00; font-style: italic; } key { color: #0000FF; font-style: italic; } .note { font-size: smaller; } text.block_left { margin-left: 15px; display: block; } text.block_around { margin: 15px; display: block; } text.block_big { margin-left: 15px; display: block; } table { margin-left: 15px; border-collapse: collapse; width: auto; } th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; font-family: 'Courier New', monospace; font-size: smaller; } tr:hover {background-color:#f5f5f5;} {% endblock %} {% block content %}
The Loglan Dictionary ought to be pretty easy to use for basic translation work. However, it does contain a lot of specialized notations that the serious wordsmith might be curious about. This is where you can look up those notations.
Like any dictionary, the Loglan Dictionary has certain conventions in how it presents its information. Consider the word "kliri".
There are four parts:
The kind of information that appears in each of the parts will depend on the kind of word it is. The "meat" of Loglan are the meaning carrying words called predicates and, not surprisingly, the LOD has information about predicates that it doesn't have about other kinds of words.
The second line contains information about the word. This information may include:
The body of each definition has some English text that describes what the word means. (E.g. "
The English to Loglan part of the dictionary has the same information but rearranged. For example, the entry for "energy" is:
There is no "word information" line (We're not going to tell you where the English word came from.) although the "word origins" information appears in one place ("
There is one other change: The pu — entries have an extra case tag in front, "B". That is because abstraction operators like pu can be thought to add an extra place to the predicate. (See Loglan 1 Section 3.10.)
That's about it, except for the lists below.
| Type | Description |
|---|---|
| Acr. | acronym, E.g. DaiNaiA, "DNA" |
| Afx | affix |
| Bor. | Borrowing, a word that has been borrowed from one language, but carefully spelled so that it can't be mistaken for another kind of Loglan predicate. |
| Cpd | Compound Little Word E.g. enoi from e+no, "and not". |
| LW | Little Word, a small word used to give Loglan its grammatical structure. |
| Name | A name, a proper noun. |
| C-Prim | Composite Primitives, drawn from several target languages in a way that might make them recognizable in most of them. (See Loglan 1 Section 6.3.) |
| D-Prim | Derived Primitive, one of the primitives that follows the cultural (language, nationality, culture) or animal (male, female, infant, resembling, unspecified) declension. E.g. zebra (female), zebre (resembling), zebri (infant), zebro (male), zebru (unspecified) (See Loglan 1 Section 6.2 for a description of the cultural declension. Animal declensions were added to Loglan since Loglan 1 was published.) |
| I-Prim | International Primitives, drawn from a single word of international scope. E.g. telfo from "telephone". |
| L-Prim | Loglan Primitives, a small group of primitives that were drawn from other Loglan words. E.g. logla from the name Loglan. |
| N-Prim | Native Primitives, drawn from a single source language. E.g. dolra from the English "dollar". |
| O-Prim | Onomatopoetic E.g zbuma, to explode. |
| S-Prim | Scientific Primitive, drawn from the international vocabulary of science. E.g. lidro from Hydrogen. |
| 1-Cpx | One-term Complex E.g. ferdei, from fer+de(nl)i=Friday (5 day) |
| 2-Cpx | Two-term Complex E.g. flicea, from fli(du)+ce(nj)a=liquid-become |
| 3-Cpx | Three-term Complex E.g. tarsesmao, from tar(ci)+se(n)s(i)+ma(dz)o=star-science-make. |
| 4-Cpx | Four-term Complex E.g. blidensaecko, from bli(cu)+den(ro)+sa(ns)e+cko(zu)=possible-danger-sense-cause |
Here are some common usages. The forms that could actually appear are infinitely varied, and the best reference for that is the text Loglan 1.
| Usage | Description |
|---|---|
| le — | instance of (See Loglan 1 Section 4.8.) |
| lo — | mass term (See Loglan 1 Section 4.9.) |
| la — | as a name (See Loglan 1 Section 4.7.) |
| lio — | as a number (See Loglan 1 Section 4.26.) |
| nu —, fu —, ju — | conversion (argument permutation) (See Loglan 1 Section 3.8.) |
| po —, pu —, zo — | abstraction (See Loglan 1 Section 3.10.) |
| lopo —, lepu —, etc | some combination of the above. |
These are the abbreviations that indicate the part of speech a definition represents.
| Grammar Code | Description |
|---|---|
A list of case tags, taken from Loglan 1, Table 4.1.
| B | beu | Bekti | (object) | '-/in' | Patients, Parts, Properties |
| C | cau | Canli | (quantity) | 'by/for' | Quantities, Amounts, Values |
| D | dio | Dirco | (direction) | 'to/for' | Recipients, Beneficiaries, Destinations |
| F | foa | Folma | (full) | 'in/of' | Wholes, Sets, Collectivities |
| J | jui | Junti | (young) | 'than' | Lessers in greater/lesser than relations |
| K | kao | Kakto | (act) | '-/by' | Actors, Agents, Doers |
| N | neu | Nerbi | (necessary) | 'under' | Conditions, Fields, Circumstances |
| P | pou | Proju | (produce) | '-' | Products, Outputs, Purposes |
| G | goa | Groda | (big) | 'than' | Greaters in greater/lesser than relations |
| S | sau | Satci | (start) | 'from' | Sources, Origins, Reasons, Causes |
| V | veu | Vetci | (event) | 'by/via' | Events, States, Deeds, Means, Routes, Effects |
Here are the initials of the various authors of individual words. As you can see, we're still tracking these down.
| Initials | Full Name | Notes |
|---|---|---|
| AFL | ? | |
| APL | Alex Leith | |
| AW | Andrew Wallace | |
| BW | Birrell Walsh | |
| CF | Colin Fine | |
| CJB | Chuck Barton? | |
| DB | ? | |
| EM | Emerson Mitchell | |
| FR | Faith Rich | |
| HA | Heike Amelung | |
| JBS | ? | |
| JC | John Cowan | |
| JCB | James Cooke Brown | |
| JF | Jerome Frazee | |
| JFB | Jenny Brown | |
| JFC | James Carter | (?) questionable |
| JJ | James Jennings | |
| JLS | Jim Smith | Source: Lognet - Purda 92-2 |
| JLT | Jeremy Taylor | |
| JPC | John Parks-Clifford | |
| JR | ? | |
| JRK | JR Kennaway | |
| JT | ? | |
| JWK | ? | |
| KAC | Kieran A. Carroll | |
| KAD | ? | |
| KS | Kirk Sattley | (?) questionable |
| L1 | Loglan 1 | The standard textbook on Loglan |
| L4 | Loglan 4&5 | The printed-on-paper book, 1975 version of the dictionary. |
| MD | Michael Demoulin | |
| MGE | ? | |
| MP | ? | |
| MWZ | Mark W. Zacharias | |
| NT | ? | |
| PI | Paloma Ibanez | |
| RAM | Robert McIvor | |
| RH | M. Randall Holmes | |
| RRM | ? | |
| RWJ | Ron W. Johnson | |
| SLC | Second Life | Internet online conversation |
| SLR | Steve Rice | |
| SRL | Scott Layson or Sheldon Linker | Both early L students at San Diego |
| TB | ? | |
| TED | ? | |
| UA | Unknown Author | |
| WDG | Bill Gober | Source: Lognet - Purda 92-2; (?) questionable. |
| WG | William G. Gober | (likely) |


{% extends "base.html" %} {% block body %}
Here is a list of publications written with {{ collaborator.name }}:
Here is a list of student projects undertaken with {{ collaborator.name }}:


public abstract class AbstractTouchEventHandler extends java.lang.Object implements java.util.Comparator<AbstractTouchEventHandler>
TouchEventDispatcher
in order to dispatch touch events to them.| Modifier and Type | Field and Description |
|---|---|
protected static int |
MAX_PRIORITY
The maximum priority of an event handler.
|
protected static int |
MIN_PRIORITY
The minimum priority of an event handler.
|
| Constructor and Description |
|---|
AbstractTouchEventHandler(int priority,
TabSwitcher tabSwitcher,
int dragThreshold)
Creates a new handler, which can be managed by a
TouchEventDispatcher in order to
dispatch touch events to it. |
| Modifier and Type | Method and Description |
|---|---|
int |
compare(AbstractTouchEventHandler o1,
AbstractTouchEventHandler o2) |
boolean |
equals(java.lang.Object obj) |
de.mrapp.android.util.gesture.DragHelper |
getDragHelper()
Returns the drag helper, which is used by the event handler to recognize drag gestures.
|
int |
getPriority()
Returns the priority of the event handler.
|
protected TabSwitcher |
getTabSwitcher()
Returns the tab switcher, the event handler belongs to.
|
android.graphics.RectF |
getTouchableArea()
Returns the bounds of the onscreen area, the handler takes into consideration for handling
touch events.
|
protected android.view.VelocityTracker |
getVelocityTracker()
The velocity tracker, which is used by the touch handler to measure the velocity of drag
gestures.
|
boolean |
handleTouchEvent(android.view.MotionEvent event)
Handles a specific touch event.
|
int |
hashCode() |
boolean |
isDragging()
Returns, whether a drag gesture is currently handled by the event handler, or not.
|
protected abstract boolean |
isDraggingAllowed()
Returns, whether performing a drag gesture is currently allowed, or not.
|
boolean |
isInsideTouchableArea(android.view.MotionEvent event)
Returns, whether a specific touch event occurred inside the touchable area of the event
handler.
|
boolean |
isReset()
Returns, whether the event handler is reset, or not.
|
protected abstract void |
onDown(android.view.MotionEvent event)
The method, which is invoked on implementing subclasses in order to handle, when a drag
gesture has been started.
|
protected abstract void |
onDrag(android.view.MotionEvent event)
The method, which is invoked on implementing subclasses in order to handle, when a drag
gesture is performed.
|
protected abstract void |
onTouchEvent()
The method, which is invoked on implementing subclasses, when a touch event is about to be
handled.
|
protected abstract void |
onUp(android.view.MotionEvent event)
Handles, when a drag gesture has been ended.
|
protected void |
reset()
Resets the event handler once a drag gesture has been ended.
|
void |
setPointerId(int pointerId)
Sets the id of the pointer, which has been used to start the current drag gesture.
|
protected static final int MAX_PRIORITY
protected static final int MIN_PRIORITY
public AbstractTouchEventHandler(int priority, @NonNull TabSwitcher tabSwitcher, int dragThreshold)
TouchEventDispatcher
in order to
dispatch touch events to it.priority
- The priority of the handler as an Integer
value. The priority must be at
least MIN_PRIORITY
and at maximum MAX_PRIORITY
tabSwitcher
- The tab switcher, the event handler belongs to, as an instance of the class TabSwitcher
. The tab switcher may not be nulldragThreshold
- The threshold of the drag helper, which is used to recognize drag gestures, in pixels
as an Integer
value The threshold must be at least 0@NonNull protected final TabSwitcher getTabSwitcher()
TabSwitcher
. The tab switcher may not be null@Nullable protected final android.view.VelocityTracker getVelocityTracker()
VelocityTracker
or null, if the velocity
tracker has not be initialized yetprotected void reset()
protected abstract boolean isDraggingAllowed()
protected abstract void onTouchEvent()
protected abstract void onDown(@NonNull android.view.MotionEvent event)
event
- The touch event, which started the drag gesture, as an instance of the class MotionEvent
. The touch event may not be nullprotected abstract void onDrag(@NonNull android.view.MotionEvent event)
event
- The last touch event of the drag gesture as an instance of the class MotionEvent
. The touch event may not be nullprotected abstract void onUp(@Nullable android.view.MotionEvent event)
event
- The touch event, which ended the drag gesture, as an instance of the class MotionEvent
or null, if no fling animation should be triggeredpublic final boolean isReset()
@CallSuper public boolean isDragging()
public final int getPriority()
Integer
value@Nullable public android.graphics.RectF getTouchableArea()
RectF
or null, if the area is not
restrictedpublic final boolean isInsideTouchableArea(@NonNull android.view.MotionEvent event)
event
- The touch event, which should be checked, as an instance of the class MotionEvent
. The touch event may not be null@NonNull public final de.mrapp.android.util.gesture.DragHelper getDragHelper()
public final void setPointerId(int pointerId)
pointerId
- The id, which should be set, as an Integer
value or -1, if no drag gesture is
currently startedpublic final boolean handleTouchEvent(@NonNull android.view.MotionEvent event)
event
- The event, which should be handled, as an instance of the class MotionEvent
.
The event may not be nullpublic final int compare(AbstractTouchEventHandler o1, AbstractTouchEventHandler o2)
compare
in interface java.util.Comparator<AbstractTouchEventHandler>
public final int hashCode()
hashCode
in class java.lang.Object
public final boolean equals(java.lang.Object obj)
equals
in interface java.util.Comparator<AbstractTouchEventHandler>
equals
in class java.lang.Object


Aaron Froehlich
Aaron has always loved problem-solving. From a young age, when he wanted to take a break from homework, he would head to math and physics problems. Aaron has a degree in comparative world religions from Friends World, an international school that allowed him to study in the Middle East, India and Asia. This rich educational experience permanently infected Aaron with a bug for traveling and backpacking.
What started as "going where the cool kids are hanging out" turned into a deeper working relationship for Aaron. He believes in continuous personal integration, innovation, and the pursuit of excellence; he has found CoLab the ideal place to put his beliefs into practice.
Aaron has 15 years of experience as a web developer and consultant, a journey that has allowed him to ride various emerging development waves, including JavaScript, AJAX, Flash, object-oriented programming, MVC, Ruby and responsive design. He currently specializes in Drupal development. In his spare time, Aaron contributes to Drupal 8 and experiments with Ansible, an IT automation framework. He has meditated daily since the mid-90s. Aaron regularly plays basketball, softball, billiards, and supports his two sons in their local First Lego League Robotics club.


Midterms' Topics
Cascading Style Sheets by Håkon Wium Lie and Bert Bos
language used to specify the presentation of structurally marked up documents
The at-rule is a statement that provides CSS with instructions to perform or how to behave.
A CSS selector is the part of a CSS rule set that actually selects the content you want to style. Let’s look at all the different kinds of selectors available, with a brief description of each.
CSS pseudo-classes are used to add special effects to some selectors. You do not need to use JavaScript or any other script to use those effects.
The LiveScript language was designed at Netscape Communications to make the Java support in Netscape Navigator more accessible to non-Java programmers. LiveScript, like any scripting language, is a loosely-typed language. It is intended for a large audience of Web designers and developers.
In December 1995, LiveScript was renamed JavaScript and released as part of Netscape Navigator 2.0. Except for marketing purposes, JavaScript has nothing to do with the Java language developed and maintained by Sun Microsystems. The Web community started then to manipulate the content of Web documents, in order to bring interactivity and typography to the formerly static Web.
Developers: Netscape Communications Corporation, Mozilla Foundation, Ecma International
ECMAScript (or ES) is a trademarked scripting-language specification standardized by Ecma International in ECMA-262. It was created to standardize JavaScript.
Iaculis ac volutpat vis non enim gravida nisi faucibus posuere arcu consequat
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.
Feugiat accumsan lorem eu ac lorem amet accumsan donec. Blandit orci porttitor.


When you look at a site's Resources, within the Resources window you will see the Title, Size, author ("Created By"), and Last Modified date.
If you have sufficient permissions, you can click Edit
to
revise a Resource item, at which time you can also see Creation Time
and Last Modified By metadata.
To view a Resource folder's subfolders, click the plus sign
(+
) on the folder icon left of the title. You can toggle
the folder open and closed by clicking the plus sign or minus sign
(-
). If the folder icon has an arrow on it, it is too
large to be expanded.


 Seriously though, it's mostly information about my furry companions, some random facts about myself, and things I like.
Furry Companions
Name: Mierin
Notable Features: Super friendly; so much snuggle.
Favorite Food: All kitty foods, sometimes cheese, and always marshmallows.
Name: Rahvin
Notable Features: Extreme fluffiness; sweet meow and purr; whiskers!
Favorite Food: He only likes the tuna treats in the maroon pouch
Name: Reiko
Notable Features: Lovable wiggle-butt; adores belly rubs; loves to swim.
Favorite Food: Literally anything, especially wood chips, that grassy bush out front, and bananas.
A Table Of My Favorite Ice Cream Flavors
Name
Description of Awesomeness
Mint Chocolate Chip
Minty green with chocolate bits
Cherry Garcia
Cherry ice cream with fudge flakes
Phish Food
Chocolate ice cream with marshmallow swirl and teeny fudge fish
Similar Content
Since my website doesn't really have a cohesive theme, I Googled "cats and ice cream" and came across this site that covers the topic of kitties eating ice cream (among other things). There is a LOT of stuff in the source code that I don't understand, but I think I was able to identify the elements that create the social media buttons. There are also a bunch of "script" tags that I think relate to the options under the various menus across the top. I hope that I'll be able to understand this site's source code a bit more in a few weeks.


Identifies enumerations that have been re-implemented.
The <cxxEnumerationReimplemented> element identifies and links to enumerations that have been re-implemented.
<cxxEnumerationReimplemented href="class_c_active.xml#class_c_active_1a4bb7613b">CActive::dSpare</cxxEnumerationReimplemented>


Editing content in TEAM Mentor is done via "Edit Mode". "Edit Mode" is only available to Editors and Administrators. To access "Edit Mode", login as either an Administrator or an Editor user and click the "Edit Mode" link in the top right of the main user
interface.
The two main ways to edit folders in TEAM Mentor are via the right-click context menu and via drag & drop operations. Right-click context menu operations allow managing the folders themselves, while drag & drop operations allow placing content inside of
folders.
The right-click content menu provides the following options: "Add View", "Add Folder", "Rename Folder", "Delete Folder", and "Exit Edit Mode". "Add View" creates a new view in the selected folder. "Add Folder" creates a new folder inside the selected folder.
"Rename Folder" allows renaming the current folder. "Delete Folder" deletes the clicked folder. "Exit Edit Mode" returns the user interface to regular mode.
Drag & drop operations allow placing existing views inside a folder. To move a view into a folder, drag it into the destination folder.


Holder
Issuer
Verifier
×
Holder registration
Please fill in this form to register.
Name
Date of birth
Cancel
Register
×
Issuer registration
Please fill in this form to register.
Name
Location
Type
University
College
School
Private institutions
Cancel
Register
×
Verifier registration
Please fill in this form to register.
Name
Location
Type
Educational institutions
Bank
Government organizations
Private organizations/corporate
Cancel
Register


“I declare that my assignment is wholly my own work in accordance with Seneca Academic Policy.
No part of this assignment has been copied manually or electronically from any other
source (including web sites) except for the information supplied by the WEB222
instructor and / or made available in this assignment for my use.
I also declare that no part of this assignment has been distributed to other students.
Name: Aria Avazkhani
Dated: July 30, 2018 “
Browser test
Google Chrome Version 67.0.3396.99
Mozilla Firefox 61.0.1


start
simple-fields
container-fields
list-fields
Summary
Submitted
single-fields
single-field:
single-field:
single-field:
container-fields
container-field-1
single-field:
single-field:
single-field:
container-field-2
single-field:
single-field:
single-field:
container-field-3
single-field:
single-field:
single-field:
list-fields
list-field-1
single-field:
single-field:
single-field:
add
list-field-2
single-field:
single-field:
single-field:
add
list-field-3
single-field:
single-field:
single-field:
add
previous step
reset
next step
summary
submit


{% extends 'store/main.html' %} {% load static %} {% block content %}
Contact
Feel free to get in touch with Us. For any Enquiry and Issue Contact Us on Mail/Helpline No./Whatsapp/Instagram/Twitter. We are always there to help you.
Mail:
<EMAIL_ADDRESS>Help line:
1800-1080-1008
Whatsapp:
+91<PHONE_NUMBER>
Instagram:
@Appetite
Twitter:
@Appetit_ke
Your FeedBack is always appreciate!
{% endblock content %}


Project Sample
This documentation is created using drapo. You can find the source code of it in this
link


Serial Killer David West, Pleads ‘Not Guilt’, After Confessing To Crimes
by Faderera FaladeGracious David West, Suspected Port Harcourt ‘serial killer’, has changed his plea to ‘not guilty’
West is changing his plea even after confessing that he lured his victims to hotels in Port Harcourt, before drugging and murdering them.
The police have a video in which West confessed to the crimes
“The defendant had earlier pleaded guilty to the 9 count charge of murder but has decided to change his plea today,” prosecutor Chidi Ekeh said.
However, his earlier confession was dismissed by his Lawyer, Vincent Chukwu who described them as having “no legal effect”
“The basis of this matter is the evidence. Let them (the prosecution) put their evidence before the court”, he told AFP.
It was further gathered that the second suspect arrested in connection to the killings, Nimi Thankgod also pleaded not guilty and was granted bail.


The translator handles full Erlang, however there are a number
of issues involving the translation of the receive construct
of Erlang (see Section 2.2 for details).
Nevertheless a particular state space exploration algorithm
(see Section 3.2.2) may impose additional limitations.
Concretely the mce_alg_safety and
mce_alg_buechi model checking algorithms
(for checking safety and liveness properties respectively)
currently implements neither a real-time nor a discrete-time
semantics for Erlang. Instead, a receive statement
with a timeout clause
where Timeout is not infinity,
is considered to have a transition enabled whenever
there is no element in the process mailbox that matches any
pattern and guard. This treatment can be changed by setting
the option (see Section 3.1) @is_infinitely_fast@
to @true@;
then non-timeout transitions prohibit non-zero timeouts from occurring.
This corresponds to the assumption that the system is infinitely
fast compared to any timers set.
The simulation algorithm (mce_alg_simulation) does implement a real-time semantics.


Dashboard
Subjects
Students
E-Shop
Transactions
User Profile
Login
Register
About Us
Help
Logout
Welcome {{ main.name }}
Select the path where you want to go


keyboard_arrow_left
keyboard_arrow_right
home
CS110
Introduction to Computer Science
JSON
JSON Example
Rouben Meschian
rmeschian@gmail.com


module Mongo: sig
.. end
This is a major client-faced module, for the high level usage.
This module includes a series of APIs that client can use directly to communicate with MongoDB. The most important functions are for insert, udpate, delete, query, get_more. They are the essential interactions that a client can have with MongoDB.
Please note that the current version of APIs here are all essential only. For example, Clients cannot set detailed flags for queries, etc. All operations here are with default flags (which is 0).
A Mongo is bound to a db and a collection. All operations will be done upon the bound db and collection only.
Please refer to MongoDB Wire Protocol for more information
exception Mongo_failed of string
the exception will be raised if anything is wrong, with a string message
type
t
the type for Mongo
Essential info of a Mongo
val get_db_name : t -> string
val get_collection_name : t -> string
val get_ip : t -> string
val get_port : t -> int
val get_file_descr : t -> Unix.file_descr
Lifecycle of a Mongo
val create : string -> int -> string -> string -> t
create a Mongo. please note that Mongo is bound to a db and a collection. e.g. create ip port db_name collection_name. May raise Mongo_failed exception.
val create_local_default : string -> string -> t
create a Mongo connecting to <IP_ADDRESS>, port 27017. e.g. create_local_default db_name collection_name. May raise Mongo_failed exception.
val destroy : t -> unit
destroy a Mongo. Please use this to destroy a Mongo once it finishes its purpose, in order to release system resources. May raise Mongo_failed exception.
Insert
val insert : t -> Bson.t list -> unit
insert a list of bson documents into MongoDB. May raise Mongo_failed exception.
Update
val update_one : t -> Bson.t * Bson.t -> unit
update the first document matched in MongoDB. e.g., update_one m (s, u);; m is the Mongo. s is the selector document, used to match the documents that need to be updated. u is the update document and any matched documents will be updated to u. May raise Mongo_failed exception.
val update_all : t -> Bson.t * Bson.t -> unit
update all documents matched in MongoDB. e.g., update m (s, u);; m is the Mongo. s is the selector document, used to match the documents that need to be updated. u is the update document and any matched documents will be updated to u. May raise Mongo_failed exception.
Delete
val delete_one : t -> Bson.t -> unit
delete the first document matched in MongoDB. e.g., delete_one m s;; m is the Mongo. s is the selector document, used to match the documents that need to be deleted. May raise Mongo_failed exception.
val delete_all : t -> Bson.t -> unit
delete the all documents matched in MongoDB. e.g., delete_one m s;; m is the Mongo. s is the selector document, used to match the documents that need to be deleted. May raise Mongo_failed exception.
Query / Find
val find : ?skip:int -> t -> MongoReply.t
find all / the default number of documents in the db and collection. May raise Mongo_failed exception.
val find_one : ?skip:int -> t -> MongoReply.t
find the first document in the db and collection. May raise Mongo_failed exception.
val find_of_num : ?skip:int -> t -> int -> MongoReply.t
find the desired number of documents in the db and collection. May raise Mongo_failed exception.
val find_q : ?skip:int -> t -> Bson.t -> MongoReply.t
find all / the default number of documents in the db and collection matching the bson query. May raise Mongo_failed exception.
val find_q_one : ?skip:int -> t -> Bson.t -> MongoReply.t
find the first document in the db and collection matching the bson query. May raise Mongo_failed exception.
val find_q_of_num : ?skip:int -> t -> Bson.t -> int -> MongoReply.t
find the desired number of documents in the db and collection matching the bson query. May raise Mongo_failed exception.
val find_q_s : ?skip:int -> t -> Bson.t -> Bson.t -> MongoReply.t
find all / the default number of documents in the db and collection matching the bson query, each document returned will only contains elements specified in the selector doc. May raise Mongo_failed exception.
val find_q_s_one : ?skip:int -> t -> Bson.t -> Bson.t -> MongoReply.t
find the first documents in the db and collection matching the bson query, each document returned will only contains elements specified in the selector doc. May raise Mongo_failed exception.
val find_q_s_of_num : ?skip:int -> t -> Bson.t -> Bson.t -> int -> MongoReply.t
find the desired number of documents in the db and collection matching the bson query, each document returned will only contains elements specified in the selector doc. May raise Mongo_failed exception.
val count : ?skip:int -> ?limit:int -> ?query:Bson.t -> t -> int
counts the number of documents in a collection
Query / Find more via cursor
val get_more_of_num : t -> int64 -> int -> MongoReply.t
get the desired number of documents via a cursor_id. e.g. get_more_of_num m cursor_id num. May raise Mongo_failed exception.
val get_more : t -> int64 -> MongoReply.t
get all / the default number of documents via a cursor_id. e.g. get_more_of_num m cursor_id num. May raise Mongo_failed exception.
Kill cursor
val kill_cursors : t -> int64 list -> unit
kill a list of cursors, to save MongoDB resources. e.g., kill_cursors m cursor_list. May raise Mongo_failed exception.
Index
type
index_option =
| |
Background of bool |
| |
Unique of bool |
| |
Name of string |
| |
DropDups of bool |
| |
Sparse of bool |
| |
ExpireAfterSeconds of int |
| |
V of int |
| |
Weight of Bson.t |
| |
Default_language of string |
| |
Language_override of string |
option for index. See http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/#db.collection.ensureIndex for more info
val get_indexes : t -> MongoReply.t
return a list of all indexes
val ensure_index : t -> Bson.t -> index_option list -> unit
ensure an index
val ensure_simple_index : ?options:index_option list -> t -> string -> unit
ensure an index (helper)
val ensure_multi_simple_index : ?options:index_option list -> t -> string list -> unit
ensure multi-fields index (helper)
val drop_index : t -> string -> MongoReply.t
drop a index
val drop_all_index : t -> MongoReply.t
drop all index of a collection
Instance Administration Commands
val change_collection : t -> string -> t
change instance collection
val drop_collection : t -> MongoReply.t
removes an entire collection from a database
val drop_database : t -> MongoReply.t
drops a database, deleting the associated data files


Start Container
If the container is stopped, this will start the container. This will not update your IP address.
Stop Container
If the container is running, this will stop the container. This will not update your IP address.
Restart Container
This will start the container if it is not running, or restart the container if it is running. If you made any changes to your IP address, this will update your that.
Switch to Bitmark
If the current network is 'testing', this will change the container to the 'bitmark' network.
Switch to Testing
If the current network is 'bitmark', this will change the container to the 'testing' network.
Check for Updates
If an update to the container is found, it will automatically be installed and the container will restart.
Show Preferences
Show the application preferences menu used to manage update and IP settings.
Refresh Window
Refresh the application window.
Bitmark Inc. 2018
THE DOCKER CONTAINER IS NOW DOWNLOADING, PLEASE WAIT A MOMENT


About Me
I am from one of the most beautiful and peaceful places on Earth, The Big Island of Hawaii. I moved to the mainland United States in search of a career, and chose Portland, Oregon to be my new home. I am currently in an amazing coding bootcamp, Epicodus, where I intended to expand my knowledge and start a career. Growing up in such a rural and isolated community has had it's interesting aspects, but has also shaped me to be who I am today.
My Hobbies and interests include:
- Web Development
- User experience design
- Playing, recording, and listening to music
- Playing and watching basketball
- Outdoor sports(hiking,surfing,running,etc.)
Education Experience
- Hilo High School (2004-2008)
- Humboldt State University(2008-2009)
- Univeristy of Hawaii at Hilo(Bachelors in Psychology 2012)
- Epicodus Design Track(in progress)
Past Projects
Wikipedia Homepage Project
The idea of this project was to try to copy the current homepage of Wikipedia homepage as well as possible. Although myself and my partner spent a fair amount of time on the project, I think that it turned out fairly well. This is the newest project that I had worked on up until this date. This project used HTML and CSS.Check it out here!
Vacation Rental Project
The purpose of this project was to try and "sell" one of these vacation rentals to a potential "buyer". This was an exercise that we did through Epicodus to practice different branches in GitHub. It was a fun project, and was one of the few projects we did that utilized different branches.This project used HTML and CSS.Check it out here!
Animal Shelter Project
This Animal Shelter Project utilized a lot of the features that I know up to this point from Epicodus. It was a project that introduced columns, along with some other features as well. This was a fun project, and I actually got a good laugh out of making it with my partner.This project used HTML and CSS.Check it out here!
Future
In the future, I hope to complete the design track at Epicodus, and move on to a career in the technology industry; ideally in User Experience Design or User Interface Design. I am confident in my ability to use the tools I will learn through Epicodus, and apply them to a long and fruitful career in the industry.


e -
Variable in class ukim.finki.mps.delay_function_generator.Elements
all the elements that are affected by this instruction
the integer is coded as follows
bits 0-7 represent the 8 REGs in the following order
bit|register
0 | A
1 | B
2 | C
3 | D
4 | E
5 | H
6 | L
bits 8-10 represent the number of memory locations required to be allowed access to by the instruction
bit|number of memory location
8 | 0
9 | 1
10 | 2
bit 11 states whether or not the instruction affects or need the stack to be operational
in all cases the value '0' stands for NO, it is NOT needed and/or it is NOT affected
while the value '1' stands for the opposite YES, it IS needed and/or it IS affected
bits are order form lowest significance in ascending order meaning the bit 0 is the least significant one,
bit 1 is the next least significant and so on.
class that contains the data which instructions uses which resources of a mP system such as registers, memory and stack
This class is specialized for 8085, since the last update in specification stated that the project is not general but specific and native to 8085
constructor for when we want to create a stub-comparison object for determining whether or not we can use a specific instruction
with the usable elements, used when we want to separate the available instructions out of the whole instruction set
to be used internally as a method that returns the integer value that needs to be added to the description encoding,
so that it states availability of the register described by its char


Colin Leath
20 January 2006
Duke University Talent Identification Program, Summer 2006 Employment
1121 West Main Street
Durham, NC 27701
I look forward to spending an intense six weeks this summer as a Teaching Assistant at TIP with some of the best students and instructors I have yet had opportunity to study with. I know what it is like to be among gifted students, since I attended a selective high school. I am now a master’s student in English and Comparative Literature at San Diego State University. To TIP I bring my experience as a facilitator and as a student and my interest in community.
For the past two years, I have been fortunate to work as a Challenge Course Facilitator. My role is to present activities that stress particular areas of team or individual development. In Group Jump Rope, for example, each person in sequence must jump the rope once without a beat being missed. Success requires that the group accept and organize around members’ abilities to jump and swing the rope. The programs I have facilitated have had as participants Brownie Girl Scouts, graduates of YMCA Youth & Family Services courses, UCLA medical residents, KPMG accountants, gung-ho franchisees, Mormon youth, and High-Tech High students, among others. I also designed and led programs for a Girl Scout troop, a student advisory board, and a volleyball team, and I co-led a Fear Factor-themed summer camp.
As a student, I have transitioned from science and engineering to the humanities. My years in high school were not the best of my life. As an undergraduate, I considered how those years could be improved. I researched identity development and optimal experience. For my thesis, I created the Meaning in Life Forum, offered it through the University of Washington’s Experimental College, and evaluated its effect on participants’ experiences of meaning in life. If I, having many advantages, free to do almost anything, to live nearly anywhere, and with the ability to succeed in many fields, could not find meaning, then hollow is the freedom so many others wish they had. Since that time, I have practiced dance, the violin, and joined a choir. I advocated living without cars. I visited ecovillages and resided in different cities, eventually moving, by bicycle, to where I am near relatives. I did all that to create a more responsive and rewarding place in which to live. I focus on literature now to learn to express visions others will value, and because I enjoy exploring realms texts call forth.
Desire for health, growth, and vitality that spring because of, not in spite of, the prevailing weather and quality of soil feeds this application and my learning how to nourish fertile land. Communication, or making common, or sharing, including the effort to truly understand what is shared, is central to growth, suggest philosopher Jürgen Habermas and author Stephen Covey. Looking for life-fostering community, I lived at Earthaven Ecovillage for two months; there I learned about heartshares, Open Space Technology, and consensus minus one. I visited Madre Grande Monastery, Shakti Rising, and The Farm Community. I lived with Quakers and attended Friends’ meetings. I participated in the third Toward Car-Free Cities conference, and I helped organize several Ishmael and Integral Transformative Practice groups.
I can, therefore, contribute to courses in wisdom, utopian dreams, and leadership. However, because I am training to teach the subjects, and wish to learn them better myself, I would especially like to assist courses in writing and literature. There are other areas I have less experience in, but would still be able to contribute to, given that I have three school-free weeks to prepare prior to the start of your first term. I have enclosed a list of some of the courses that interest me.
I look forward to working with you.
Colin Leath


jl777c
01-May-19 08:01 AM
these are not tech issues, i will stay out of it
if it isnt a tech issue, there is no deterministic solution and it can be debated, literally forever and usually end up with two or more sides, totally convinced they are correct.
there are not obvious compiler or linker errors to fix
no algorithms to deal with
others are tasked to deal with such issues, I do tech, that can be shown to work without debates
just one question about end users and linux. how many android phones are there? none of those phones are used by any end users, is your position?
osx is also arguably a close relative to linux, so apple products are not used by any end users either?
i think you are totally underestimating the pervasiveness of linux
and yes, I know there are many forks of linux that are not linux anymore, but my point is that without linux in the first place, they wouldnt exist
oh, and a large number of websites running linux, i guess those are all just hobbyists
so we have a total disagreement about some fundamental things and if your position is that linux is just for hobbyists or embedded software companies, then it seems for you komodo can only be for a very small number of people, but to me I know komodo will allow crypto to be used by the masses. But the gap is too big when your position is that linux is just for hobbyists
2
like i said, non-deterministic as shown by how you can believe linux cannot get end users


Fun Facts About Bugs!
1)Houseflies find sugar with their feet, which are 10 million times more sensitive than human tongues.
2)Ticks can grow from the size of a grain of rice to the size of a marble.
3)Approximately 2,000 silkworm cocoons are needed to produce one pound of silk.
4)While gathering food, a bee may fly up to 60 miles in one day.
5)Ants can lift and carry more than fifty times their own weight.
6)It takes about one hundred Monarch Butterflies to weigh an ounce.
7)Honeybees have to make about ten million trips to collect enough nectar for production of one pound of honey.
8)Insects have been present for about 350 million years, and humans for only 300,000 years.
9)There are nearly as many species of ants (8,800) as there are species of birds (9,000) in the world.
10)The oldest known fossil of an insect dates back 400 million years and is a springtail.


An apocalypse shakes the world. Nuclear winter thrives. In the ashes of our world a communistic nation arises. Only the will of a few can redeem our lost world.
Find Out MoreJim and Dennis have very different beliefs. Jim upholds the America way and has patriotism coursing through his veins. Dennis believes that Karl Marks created the perfect form of society within communism. Dennis's radical opinions attracts the attention of Druten, the Russian president. Druten wants Dennis by his side when he takes over the world. Through many daring and dangerous adventures Jim, Dennis, Druten, and Challenger discover a weapon that will allow Druten to rule forever. Armed with this weapon, Druten destroys the United States. With the combined power of an expanded Russian and American nuclear arsenal he plunges the world into a nuclear winter. Once the nuclear winter subsides Druten repopulates the world with his brainwashed subjects. Only Jim and a band of rebels can save what little world is left.


OSCAR NYAMEINO GICHANA
My Programming Portfolio
page-2
About
Oscar Nyameino Gichana is a passionate professional with knowledge in finance, software development, audit, business development, business management, event
management, and client relations. I aspire to combine my training to achieve excellence in all I do.
Core competencies
- People skills and Negotiation.
- Team player.
- Client Relations.
- Planning and organization.
Work History
Ujenzi Hypermarket: Online Marketing
Ujenzi Hypermarket is a dealer in quality and affordable Floor tiles, Wall tiles, Granito, kitchen tops, kitchen and bathroom accessories, ceramics, toilets , kitchen sinks and tiling solutions.
Roles and responsibilities
- Ensuring that the brand message is consistent.
- Monitoring key online marketing metrics to track success.
- Maintaining digital dashboard of Facebook account.
- Coordinating with sales team to create marketing campaigns.
- Analyzing digital data to draw key recommendations around website optimization.
- Brainstorming new and creative growth strategies.
- Identifying trends and insights, and optimizing spend and performance based on the insights.
- Measuring and reporting performance of all digital marketing campaigns
Provincial General Hospital-Nakuru: Accounting Intern.
Roles and responsibilities
- Preparing financial statements such as balance sheets, invoices and other documents.
- Reviewing and reconciling financial transactions made by the hospital.
- Learning and understanding financial processes and procedures of the hospital under supervision.
- Learning how to work as part of the accounting team in ensuring client satisfaction.
- Handling confidential information with honesty and integrity as is required by professional standards.
- Working with the Hospital Accounts System, Qafya system and other hospital systems.
- Ensuring tasks assigned are completed on time and as they are required.

Educational background
Course:Bachelor in Business Management
Institution:Moi University
Level:Fourth Year
Duration: 2016- ongoing
Program: Kenya Certificate of Secondary Education- Mean grade B+
Institution:Kakamega School
Duration: 2012- 2015
Why Software Development at Moringa
Over the past the world has undergone major changes in technologies applied generally and in various workplace. As an otgoing individual who is interested in being upto date with these technologies, I decided to take a course to learn skills relevant to software development. Why Moringa? The program at Moringa school is student focused and directed at preparing the student for the workplace enviroment. I would like to be equiped with skills that are helpful in enhancing my career.


- Upload your save file (probably at: C:/Program Files (x86)/steam/userdata/{userid}/382900/local)
- Using the JSON editor make the changes you want to the file.
- One finished, button to download your altered save file.
LockePick
FF6 Save Editor
A rough guide:
Utilities


Gridland
问题描述 :
For years, computer scientists have been trying to find efficient solutions to different computing problems. For some of them efficient algorithms are already available, these are the “easy” problems like sorting, evaluating a polynomial or finding the shortest path in a graph. For the “hard” ones only exponential-time algorithms are known. The traveling-salesman problem belongs to this latter group. Given a set of N towns and roads between these towns, the problem is to compute the shortest path allowing a salesman to visit each of the towns once and only once and return to the starting point.
Problem
The president of Gridland has hired you to design a program that calculates the length of the shortest traveling-salesman tour for the towns in the country. In Gridland, there is one town at each of the points of a rectangular grid. Roads run from every town in the directions North, Northwest, West, Southwest, South, Southeast, East, and Northeast, provided that there is a neighbouring town in that direction. The distance between neighbouring towns in directions North-South or East-West is 1 unit. The length of the roads is measured by the Euclidean distance. For example, Figure 7 shows 2 * 3-Gridland, i.e., a rectangular grid of dimensions 2 by 3. In 2 * 3-Gridland, the shortest tour has length 6.
Figure 7: A traveling-salesman tour in 2 ? 3-Gridland.
输入:
For each scenario, the grid dimensions m and n will be given as two integer numbers in a single line, separated by a single blank, satisfying 1 < m < 50 and 1 < n < 50.
输出:
样例输入:
2 2 2 2 3
样例输出:
Scenario #1: 4.00 Scenario #2: 6.00
解题代码:
//* @author: ccQ.SuperSupper import java.io.*; import java.util.*; import java.math.*; public class Main { public static void main(String[]args) throws Exception{ int t,n,m,cs=1; double ans; Scanner cin = new Scanner(System.in); //Scanner cin = new Scanner(new FileInputStream("input.txt")); t = cin.nextInt(); while(t--!=0){ n = cin.nextInt(); m = cin.nextInt(); System.out.println("Scenario #"+cs+":"); ++cs; if(n%2==0 || m%2==0){ System.out.printf("%.2f\n\n", (double)n*m); } else{ System.out.printf("%.2f\n\n",(double) ((double)n*m-1+Math.sqrt(2.0))); } } } }
有谁知道直接遍历的方法中第8行是什么意思嘛？
顶一个 赞一个
找bug好专业的说
不需要输出，只要函数返回值正确就行
博主的C++功底真是好
3，求得所有的为的总和sum—->所有数的总和
printf( "Not Possible" );—->printf("impossible");
对吗？
5.1处，反了；“上一个操作符的优先级比操作符ch的优先级大，或栈是空的就入栈。”如代码所述，应为“上一个操作符的优先级比操作符ch的优先级小，或栈是空的就入栈。”
算法还停留在大学的知识中
很全很强大！
红绯鱼：
牛逼牛逼
这个问题别太纠结了，不同的编译器结果不一
[…] 如果此题没有要求 相对位置不变，可以参考文章：http://www.acmerblog.com/interview-9-2427/ […]


{% load static %}
{% load static %}
Start Bootstrap
Home
(current)
About
Services
Logout
Lets talk!
{% ifnotequal request.session.user "none" %} {% if request.session.user == 'admin' %}
Add User
Delete Uer
Configure chatroom
{% else %}
Join chatroom
{% endif %} {% endifnotequal %}
{% if request.session.user == 'none' %}
Sign In
Email address
Password
Remember password
Is admin ?
Sign in
{% else %}
{% endif %}


Avaje Http Client
| License | Source | API Docs | Issues | Releases |
|---|---|---|---|---|
| Apache2 | Github | Javadoc | Github |
A lightweight wrapper to the JDK 11+ Java Http Client.
- Requires Java 11+
- Adds a fluid API for building URLs and payloads
- Adds JSON marshalling/unmarshalling of request and response using Jackson, Gson or avaje-jsonb
- Gzip encoding/decoding
- Logging of request/response logging
- Interception of request/response
- Built in support for authorization via Basic Auth and Bearer Tokens
- Provides async and sync API
JDK HttpClient Introduction
Some introductions to the JDK HttpClient:
- OpenJDK HttpClient Introduction
- A closer look at the Java 11 HTTP Client
- Javadoc for JDK HttpClient
Client API generation
We can define a java interface with annotations and have a Java annotation processor generate the client implementation (similar to Retrofit, Feign and JAX-RS client).
- Generates the implementation as source code via annotation processing
- No reflection and no use of dynamic proxies
- Targets avaje-http-client / JDK HttpClient only
This client API generation targets avaje-http-client / JDK HttpClient only and uses source code generation via annotation processing so there is no use of reflection/dynamic proxies to slow things down.
Example client API
@Client
interface GitHub {
@Get("/repos/{owner}/{repo}/contributors")
List<Contributor> contributors(String owner, String repo);
}
Using client API
HttpClient client = HttpClient.builder()
.baseUrl("https://api.github.com")
//.bodyAdapter(new JsonbBodyAdapter())
.build();
// obtain API implementation
GitHub github = client.create(GitHub.class);
try {
// use the api/interface
List<Contributor> contributors = github.contributors("rbygrave", "junk");
} catch (HttpException ex) {
if (ex.getCause() != null) {
// some IO/Interrupted exception happened while sending request.
} else {
//Use HttpException utility methods to access response status and handle/deserialize error body
}
}
}
API allowing async or sync use via HttpCall
@Client
interface GitHub {
@Get("/repos/{owner}/{repo}/contributors")
HttpCall<Contributor> contributors(String owner, String repo);
}
Getting started
Dependencies
Maven
Add avaje-http-client as a dependency.
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-http-client</artifactId>
<version>${avaje.http.client.version}</version>
</dependency>
Client API generation
For the client API generation, we need to add avaje-http-api as a dependency.
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-http-api</artifactId>
<version>${avaje.http.api.version}</version>
</dependency>
Client API - Annotation processor
Add the avaje-http-client-generator annotation processor.
<!-- Annotation processors -->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-http-client-generator</artifactId>
<version>${avaje.http.api.version}</version>
<scope>provided</scope>
</dependency>
Gradle
Add dependencies for avaje-http-client and jackson-databind.
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'io.avaje:avaje-http-client:1.35'
...
}
When using Client API we additionally need avaje-http-api and the avaje-http-client-generator annotation processor.
dependencies {
implementation 'io.avaje:avaje-http-client:1.35'
implementation 'io.avaje:avaje-http-api:1.17'
annotationProcessor 'io.avaje:avaje-http-client-generator:1.35'
...
}
Limitations
Current notable limitations are:
- No support for multipart-form body (Though some libraries provide bodyPublishers that can be used to send multi-part data)
- Retry (when specified) does not currently apply to async request processing
Quick Overview
HttpClient
Create an HttpClient with a base URL and BodyAdapter (plus other options as necessary like retry, interceptors etc). It can be used to create requests. Requests can be executed synchronously or asynchronously with CompletableFuture.
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
.bodyAdapter(new JsonbBodyAdapter())
//.bodyAdapter(new JacksonBodyAdapter())
//.bodyAdapter(new GsonBodyAdapter(new Gson()))
.build();
Example GET
Customer customer = client.request()
.path("customers/42")
.GET()
.bean(Customer.class);
List<Product> products = client.request()
.path("products")
.GET()
.list(Product.class);
HttpResponse<String> hres = client.request()
.path("health")
.GET()
.asString();
Example GET Async
client.request()
.path("hello")
.GET()
.async().asString() // CompletableFuture<HttpResponse<String>>
.whenComplete((hres, throwable) -> {
if (throwable != null) {
// CompletionException
...
} else {
// HttpResponse<String>
int statusCode = hres.statusCode();
String body = hres.body();
...
}
});
Sync and Async
We can make requests in simple blocking manner or via async()
which uses CompletableFuture
.
The JDK HttpClient provides a number of BodyHandlers
including reactive Flow based subscribers. When executing the requests in
asynchronous style the responses are processed in a reactive way. Generally
CompletableFuture.whenComplete()
will be called only when the
response is ready.
Using withHandler(...) we can use any of the existing handlers or make our own HttpResponse.BodyHandler implementation.
Loom vs Async
With Loom we will be able to use simple blocking requests and get a similar
performance as the async()
requests. This is an important factor
to keep in mind. To use loom, simply add a virtual thread executor to the http client builder.
See 10K requests - Loom vs Async
HttpClient
HttpClient is effectively a wrapper of java.net.http.HttpClient
with extra features for request interception, body adapters, retry, etc.
Create a HttpClient with a base URL and a BodyAdapter (e.g. JsonbBodyAdapter). Set other options like retry and request interceptors as necessary.
Reference HttpClient.Builder
Creating HttpClient
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
.bodyAdapter(new JsonbBodyAdapter())
// .bodyAdapter(new JacksonBodyAdapter())
// .bodyAdapter(new GsonBodyAdapter(new Gson()))
.build();
From the HttpClient instance we create requests and execute them.
Create and execute requests
HttpResponse<String> hres = client.request()
.path("hello")
.GET()
.asString();
Json - BodyAdapter
avaje-http-client provides a BodyAdapter interface with implementations for Jackson, Gson and Avaje-Jsonb to adapt request and response body content from JSON to java types and from java types to JSON.
Using Avaje-Jsonb
To use avaje-jsonb for serialization of request and response body content to and from JSON we need to:
1. Add avaje-jsonb dependency
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb</artifactId>
<version>${avaje.jsonb.version}</version>
</dependency>
2. Register JsonbBodyAdapter
Register the JsonbBodyAdapter with the HttpClient builder. We can supply a jsonb instance to JsonbBodyAdapter or just use defaults. For example:
Jsonb jsonb = Jsonb.builder().build();
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
.bodyAdapter(new JsonbBodyAdapter(jsonb))
.build();
Avaje-jsonb uses APT source code generation to generate
adapters for types annotated with @Json
. This makes it a fast and light dependency, especially good for
http clients, CLI applications and use with GraalVM native images.
Using Jackson
To use Jackson for serialization of request/response body content to/from JSON we need to:
1. Add jackson-databind dependency
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.2</version>
</dependency>
2. Register JacksonBodyAdapter
Register a JacksonBodyAdapter with the HttpClient builder. We cab provide JacksonBodyAdapter an ObjectMapper that has modules and configuration. For example:
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
.bodyAdapter(new JacksonBodyAdapter(objectMapper))
.build();
Using Gson
To use Gson for serialization of request/response body content to/from JSON we need to:
1. Add gson dependency
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
2. Register GsonBodyAdapter
Register the GsonBodyAdapter with the HttpClient builder. For example:
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
.bodyAdapter(new GsonBodyAdapter(new Gson()))
.build();
Request body
Instances of java.net.http.HttpRequest.BodyPublisher are used to send request body content. The JDK HttpClient comes with a number of implementations for different situations. You can use your own implementation as well if you so desire.
avaje-http-client adds URL encoded form and body adapters using Jackson and Gson to convert body content to/from JSON and java beans/types.
Request Body
- An Object that is written by the BodyAdapter, e.g. JsonbBodyAdapter writes as JSON content
- formParam() for url encoded form
- byte[], String, Path (file), InputStream
- Any HttpRequest.BodyPublisher
Object as JSON
When we create the HttpClient, we can register a message body handler. When these are registered, we can call body(object)
to write the body content as JSON.
Example: POST object as json
Hello bean = new Hello(42, "rob", "hello world");
HttpResponse<Void> res = client.request()
.path("hello")
.body(bean)
.POST()
.asVoid();
formParam
Calling formParam()
adds URL encoded name-value pairs, and send body content as application/x-www-form-urlencoded
.
Example: POST using formParams
HttpResponse<Void> res = client.request()
.path("register/user")
.formParam("name", "Bazz")
.formParam("email"<EMAIL_ADDRESS>.formParam("url", "http://foo.com")
.formParam("startDate", "2020-12-03")
.POST()
.asVoid();
Path (file)
This uses HttpRequest.BodyPublishers.ofFile(file)
to
stream file content as the request body.
Example: PUT file Path
Path file = ...;
HttpResponse<String> res = client.request()
.path("upload")
.body(file)
.PUT()
.asString();
InputStream
This uses HttpRequest.BodyPublishers.ofInputStream(supplier)
to stream the request body content from the InputStream.
Example: PUT InputStream
InputStream inputStream = ...;
HttpResponse<String> res = client.request()
.path("upload")
.body(inputStream)
.PUT()
.asString();
HttpRequest.BodyPublisher
We can pass any HttpRequest.BodyPublisher
into body()
. Refer to HttpRequest.BodyPublishers
for ones that come with JDK HttpClient.
Example: Use any BodyPublisher
HttpResponse<Void> res = client.request()
.path("whazzzup")
.body(HttpRequest.BodyPublishers.ofString("silly example"))
.PUT()
.asVoid();
Summary of default BodyPublishers
| BodyPublishers.noBody() | Sends no request body. |
| BodyPublishers.ofByteArray() | byte[] |
| BodyPublishers.ofString() | String, additional charset option |
| BodyPublishers.ofInputStream() | InputStream |
| BodyPublishers.ofFile(Path file) | Path with various options |
| BodyPublishers.fromPublisher(...) | various options |
Response body
java.net.http.HttpResponse.BodyHandler is the interface used to handle response bodies. The JDK HttpClient provides a number of BodyHandlers including reactive Flow based subscribers.
avaje-http-client has APIs to use the common ones such as String, Void, byte[] etc
and withHandler()
to use any BodyHandler implementation.
bean(Class<T>)
Return the response via BodyAdapter as a java bean/type (typically JSON). The BodyAdapter
decodes from a byte[]
. Gzip decoding occurs based on Content-Encoding header.
If the HTTP status code is in the error range this throws an HttpException. From the HttpException we can get the underlying HttpResponse and error response body.
Customer customer = client.request()
.path("customers/42")
.GET()
.bean(Customer.class);
list(Class<T>)
Return the response via BodyAdapter as a list of java beans/type (typically JSON). The BodyAdapter
decodes from byte[]
. Gzip decoding occurs based on Content-Encoding header.
If the HTTP status code is in the error range this throws an HttpException. From the HttpException we can get the underlying HttpResponse and error response body.
List<Customer> customers = client.request()
.path("customers")
.GET()
.list(Customer.class);
stream(Class<T>)
Return the response via BodyAdapter as a stream of java beans/type.
The response media type is expected to be application/x-json-stream
.
Internally this uses HttpResponse.BodyHandlers.asLines()
to
get a stream of lines Stream<String>
. In this case the BodyAdapter
decodes from String
content and there is no gzip decoding supported.
If the HTTP status code is in the error range this throws an HttpException. From the HttpException we can get the underlying HttpResponse and error response body.
Stream<Customer> customers = client.request()
.path("customers")
.GET()
.stream(Customer.class);
asVoid()
Return as HttpResponse<Void>
but the response
content is still available to be read in the case of error response.
If the HTTP status code is in the error range this throws an HttpException. From the HttpException we can get the underlying HttpResponse and error response body.
HttpResponse<Void> hres = client.request()
.path("hello")
.GET()
.asVoid();
asDiscarding()
Return a HttpResponse<Void>
but the response
content is always discarded. Unlike asVoid()
, error content will not be available.
We use asDiscarding() when we only ever want the status code and headers etc and never want the response body.
HttpResponse<Void> hres = client.request()
.path("hello")
.GET()
.asDiscarding();
asString()
Return as HttpResponse<String>
.
HttpResponse<String> hres = client.request()
.path("hello")
.GET()
.asString();
as()
Return as HttpResponse<T>
.
HttpResponse<T> hres = client.request()
.path("hello")
.GET()
.as(T.class);
withHandler()
Using withHandler()
we can use any BodyHandler to process the response.
HttpResponse<InputStream> hres = client.request()
.path("hello/stream")
.GET()
.withHandler(BodyHandlers.ofInputStream());
Summary of default BodyHandlers
| BodyHandlers.discarding() | Discards the response body |
| BodyHandlers.ofByteArray() | byte[] |
| BodyHandlers.ofString() | String, additional charset options |
| BodyHandlers.ofLines() | Stream<String> |
| BodyHandlers.ofInputStream() | InputStream |
| BodyHandlers.ofFile(Path file) | Path with various options |
| BodyHandlers.ofByteArrayConsumer(...) | |
| BodyHandlers.fromSubscriber(...) | various options |
| BodyHandlers.fromLineSubscriber(...) | various options |
HttpException
An HttpException is thrown when the status code is not in the 2XX range and the call is one of bean(), list(), stream(), asVoid().
HttpException effectively wraps the HttpResponse and provides helper methods to get the response body as String, byte[] or bean (via the registered body adapter).
int statusCode = httpException.statusCode();
// the underlying HttpResponse
HttpResponse<?> httpResponse = httpException.httpResponse()
int statusCode = httpResponse.statusCode();
// helper methods to read the response body
String errorBodyString = httpException.bodyAsString();
byte[] errorBodyBytes = httpException.bodyAsBytes();
// helper method to read the response body as a bean (typically using Jackson/Gson)
MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
Reference javadoc HttpException
Async
All requests can be made using async
returning CompletableFuture
.
Commonly the whenComplete()
callback will be used to process the async responses.
The bean(), list(), stream() and asVoid() responses throw a
HttpException
if the status code is not in the 2XX range.
Reference API javadoc HttpAsyncResponse
Example: async().asString()
client.request()
.path("hello/world")
.GET()
.async().asString()
.whenComplete((hres, throwable) -> {
if (throwable != null) {
...
} else {
int statusCode = hres.statusCode();
String body = hres.body();
...
}
});
Example: async().bean(Class<T>)
client.request()
.path("customer").path(42)
.GET()
.async().bean(Customer.class)
.whenComplete((customer, throwable) -> {
if (throwable != null) {
HttpException httpException = (HttpException) throwable.getCause();
int statusCode = httpException.getStatusCode();
// maybe convert json error response body to a bean (using Jackson/Gson)
MyErrorBean errorResponse = httpException.bean(MyErrorBean.class);
..
} else {
// use customer
...
}
});
Example: async().withHandler()
The example below is a line subscriber processing response content line by line.
CompletableFuture<HttpResponse<Void>> future = client.request()
.path("hello/lineStream")
.GET().async()
.withHandler(HttpResponse.BodyHandlers.fromLineSubscriber(new Flow.Subscriber<>() {
@Override
public void onSubscribe(Flow.Subscription subscription) {
subscription.request(Long.MAX_VALUE);
}
@Override
public void onNext(String item) {
// process the line of response content
...
}
@Override
public void onError(Throwable throwable) {
...
}
@Override
public void onComplete() {
...
}
}))
.whenComplete((hres, throwable) -> {
int statusCode = hres.statusCode();
...
});
Testing with async() and join()
When writing tests using .async()
we can use .join()
such that the current
thread waits for the async processing to complete. We then execute asserts knowing the async processing
has completed.
Example: join()
client.request()
.path("customer").path(42)
.GET()
.async().bean(Customer.class)
.whenComplete((customer, throwable) -> {
...
}).join(); // wait for async processing to complete
// can assert here after the join() if desired
assertThat(...)
Executor and common pool
JDK-8204339 - HTTP Client Dependent tasks should run in the common pool
means that by default, async callbacks are executed using the ForkJoinPool.commonPool()
even when an
Executor
is assigned to the HttpClient
. This can be unexpected behavior, also refer
to this stackoverflow discussion
on this behavior.
HttpCall
If we are creating an API and want the client code to choose to execute
the request asynchronously or synchronously then we can use call()
.
This is similar to Retrofit Call for people who are familiar with that.
The client can then choose to execute() the request synchronously or choose async() to execute the request asynchronously.
Reference API javadoc HttpCall
Example: call()
HttpCall<List<Customer>> call = client.request()
.path("customers")
.GET()
.call().list(Customer.class);
// Either execute synchronously
List<Customer> customers = call.execute();
// Or execute asynchronously
call.async()
.whenComplete((customers, throwable) -> {
...
});
Retry (Sync Requests Only)
To add Retry funtionality, use .retryHandler(yourhandler)
on the builder to provide your retry handler.
The RetryHandler interface provides two methods, one for status exceptions (e.g. you get a 4xx/5xx from the server) and another for exceptions thrown by the underlying client (e.g. server times out or client couldn't send request).
Here is example implementation of RetryHandler.
public final class ExampleRetry implements RetryHandler {
private static final int MAX_RETRIES = 2;
@Override
public boolean isRetry(int retryCount, HttpResponse<?> response) {
final var code = response.statusCode();
if (retryCount >= MAX_RETRIES || code <= 400) {
return false;
}
return true;
}
@Override
public boolean isExceptionRetry(int retryCount, HttpException response) {
//unwrap the exception
final var cause = response.getCause();
if (retryCount >= MAX_RETRIES) {
return false;
}
if (cause instanceof ConnectException) {
return true;
}
return false;
}
Authorization
avaje-http-client has built in support for basic auth and bearer token based authorisation.
Basic Auth
We can use BasicAuthIntercept
to intercept all requests adding a Authorization: Basic ...
header.
Example
HttpClient client = HttpClient.builder()
.baseUrl(baseUrl)
...
.requestIntercept(new BasicAuthIntercept("myUsername", "myPassword")) <!-- HERE
.build();
Bearer token Authorization - AuthTokenProvider
For Authorization using Bearer tokens that are obtained and expire after some time, implement
AuthTokenProvider
and register that when building the HttpClient.
Step 1. Implement AuthTokenProvider
class MyAuthTokenProvider implements AuthTokenProvider {
@Override
public AuthToken obtainToken(HttpClientRequest tokenRequest) {
MyAuthTokenResponse res = tokenRequest
.url("https://foo/v2/token")
.header("content-type", "application/json")
.body(authRequestAsJson())
.POST()
.bean(MyAuthTokenResponse.class);
Instant validUntil = Instant.now().plusSeconds(res.expiresIn()).minusSeconds(60);
return AuthToken.of(res.accessToken(), validUntil);
}
}
Step 2. Register with HttpClient
HttpClient client = HttpClient.builder()
.baseUrl("https://foo")
...
.authTokenProvider(new MyAuthTokenProvider()) <!-- HERE
.build();
Token will be obtained and set automatically
All requests using the HttpClient will automatically get an Authorization header with the retrivedBearer token added. The token will be obtained for the initial request and then renewed when the token has expired.
Logging
By default request response logging is built in (via RequestLogger
)
and we enable it via setting the log level to DEBUG
or TRACE
for io.avaje.http.client.RequestLogger
Example: Logback
<logger name="io.avaje.http.client.RequestLogger" level="trace"/>
DEBUG
Summary logging that includes the response status code and execution time is logged
at DEBUG
level.
TRACE
Logging that includes the request and response headers plus the body
content is logged at TRACE
level.
Suppression
Logging is suppressed for Authorization headers and requests used by
AuthTokenProvider. Additionally logging can be
suppressed on requests via HttpClientRequest.suppressLogging()
.
Client API
We can define an interface and have the implementation generated. Similar to JAX-RS Client, Retrofit, Feign.
When using Client API we need to add a dependency for avaje-http-api which has the annotations and also add the annotation processor avaje-http-client-generator.
Getting started
Goto Getting started with Client API for step by step instructions to get started.
@Client
If we are creating the interface we can put @Client
on the interface
to indicate that the generator should generate an implementation for it.
Example client API
@Client
interface GitHub {
@Get("/repos/{owner}/{repo}/contributors")
List<Contributor> contributors(String owner, String repo);
}
@Client.Import
If the interface is already defined (in say another project) then we can instead
use @Client.Import
to indicate to the generator that it should
generate an implementation for the interface defined by @Client.Import
.
We can put the @Client.Import
on a package-info
or any type.
Most commonly we would put it on the top level package-info.
Example client import
@Client.Import(types = org.foo.MyInterface.class)
package org.bar;
import io.avaje.http.api.Client;
Obtain/use API
We obtain the API implementation via httpClient.create(T)
passing
our client interface type T.
Example: obtain implementation
final HttpClient httpClient = HttpClient.builder()
.baseUrl("https://api.github.com")
.bodyAdapter(new JsonbBodyAdapter())
.build();
// obtain API implementation
final Github github = httpClient.create(Github.class);
// use it
List<Contributor> contributors = github.contributors("ebean-orm", "ebean");
Generated implementation
The avaje-http-client-generator annotation processor generates the
implementation as java source code. The generated source is typically found in:
target/generated-sources/annotations
For more on IntelliJ IDEA setup of generated source.
Example: Generated source
The generated code for the Github
interface above is:
package org.example.httpclient;
import io.avaje.http.api.*;
import io.avaje.http.client.HttpClient;
import java.util.List;
import org.example.Contributor;
import org.example.Github;
@Generated("avaje-http-client-generator")
public class Github$HttpClient implements Github {
private final HttpClient clientContext;
public Github$HttpClient(HttpClient ctx) {
this.clientContext = ctx;
}
// GET /repos/{owner}/{repo}/contributors
@Override
public List<Contributor> contributors(String owner, String repo) {
return clientContext.request()
.path("repos").path(owner).path(repo).path("contributors")
.GET()
.list(Contributor.class);
}
}
Response types
Below is a table of the API response types can be used and the resulting generated code.
| Method response type | Generated code |
|---|---|
| void | asVoid() |
| String | asPlainString().body() |
| T | bean(T.class) |
| List<T> | list(T.class) |
| Stream<T> | stream(T.class) |
| HttpResponse<Void> | asVoid() |
| HttpResponse<String> | asString() |
| HttpResponse<T> | as(T.class) |
| HttpResponse<byte[]> | asByteArray() |
| HttpResponse<InputStream> | asInputStream() |
| HttpResponse<Stream<String>> | asLines() |
| CompletableFuture<T> | async().bean(T.class) |
| CompletableFuture<List<T>> | async().list(T.class) |
| CompletableFuture<Stream<T>> | async().stream(T.class) |
| CompletableFuture<HttpResponse<Void>> | async().asVoid() |
| CompletableFuture<HttpResponse<String>> | async().asString() |
| CompletableFuture<HttpResponse<T>> | async().as(T.class) |
| CompletableFuture<HttpResponse<byte[]>> | async().asByteArray() |
| CompletableFuture<HttpResponse<InputStream>> | async().asInputStream() |
| CompletableFuture<HttpResponse<Stream<String>>> | async().asLines() |
| HttpCall<T> | call().bean(T.class) |
| HttpCall<List<T>> | call().list(T.class) |
| HttpCall<Stream<T>> | call().stream(T.class) |
| HttpCall<HttpResponse<Void>> | call().asVoid() |
| HttpCall<HttpResponse<String>> | call().asString() |
| HttpCall<HttpResponse<T>> | call().as(T.class) |
| HttpCall<HttpResponse<byte[]>> | call().asByteArray() |
| HttpCall<HttpResponse<InputStream>> | call().asInputStream() |
| HttpCall<HttpResponse<Stream<String>>> | call().asLines() |
HttpResponse.BodyHandler parameter
The method can also declare one parameter of type java.net.http.HttpResponse.BodyHandler
and this will be used to handle the response body. This can be a specific generic type like
BodyHandler<Path>
or more general type like BodyHandler<T>
.
@Get("/{id}")
HttpResponse<Path> getWithHandler(String id, HttpResponse.BodyHandler<Path> myHandler, String other);
The generated code uses the BodyHandler parameter to handle the response body. The resulting generated code
includes .withHandler(myHandler)
:
// GET /{id}
@Override
public HttpResponse<Path> getWithHandler(String id, BodyHandler<Path> myHandler, String other) {
return clientContext.request()
.path(id)
.queryParam("other", other)
.GET()
.withHandler(myHandler);
}
We can also use a more general handler like HttpResponse.BodyHandler<T>
.
For example:
@Get("/{id}")
<T> HttpResponse<T> getWithGeneralHandler(String id, HttpResponse.BodyHandler<T> myHandler);
The generated code uses the BodyHandler parameter to handle the response body.
// GET /{id}
@Override
public <T> HttpResponse<T> getWithGeneralHandler(String id, BodyHandler<T> myHandler) {
return clientContext.request()
.path(id)
.GET()
.withHandler(myHandler);
}
HttpRequest.BodyPublisher parameter
The method can also declare one parameter of type java.net.http.HttpRequest.BodyPublisher
and this will be used for the request body.
@Post("/{id}/foo/{name}")
HttpResponse<Void> postWithBody(String id, String name, HttpRequest.BodyPublisher body);
The generated code uses the BodyPublisher parameter as the request body .body(body)
// POST /{id}/foo/{name}
@Override
public HttpResponse<Void> postWithBody(String id, String name, BodyPublisher body) {
return clientContext.request()
.path(id).path("foo").path(name)
.body(body)
.POST()
.asVoid();
}
@Path
We can optionally put @Path
on the interface type. This path is prefixed to the
paths defined on the verb annotations @Get, @Post, @Put ...
.
For example, with @Path("/api/cats")
all the paths defined have /api/cats
prefixed.
@Client
@Path("/api/cats")
public interface Cats {
@Get("{id}")
Cat byId(UUID id);
@Get("{id}/operations")
List<Operation> operations(UUID id, OffsetDateTime since);
@Get("all")
Stream<Cat> all();
@Post
void create(Cat cat);
}
The generated paths for the methods above all have /api/cats
prefix:
// GET {id}
.path("api").path("cats").path(id)
// GET {id}/operations
.path("api").path("cats").path(id).path("operations")
// GET all
.path("api").path("cats").path("all")
// POST
.path("api").path("cats")
Path parameters
Path parameters start with {
and end with }
and matched
to method parameter names. So unlike JAX-RS we do not need a @PathParam
annotation.
For example {id}
, {startDate}
, {type}
in the path are matched to method parameters of the same name.
@Get("/{id}/{startDate}/{type}")
List<Bazz> findBazz(long id, LocalDate startDate, String type);
The generated code includes .path(id).path(startDate).path(type)
:
// GET /{id}/{startDate}/{type}
@Override
public List<Bazz> findBazz(long id, LocalDate startDate, String type) {
return clientContext.request()
.path(id).path(startDate).path(type)
.GET()
.list(Bazz.class);
}
Unlike JAX-RS we do not need a @PathParam
annotation.
@RequestTimeout
Use @RequestTimeout
to override the global response timout for a specific request.
@Client
interface CustomerApi {
@Get("/{id}")
@RequestTimeout(value = 1, ChronoUnit.SECONDS) //defaults to milliseceonds
Customer getById(long id);
}
@Header
Use @Header
for a header parameter.
It the header parameter name is not explicitly specified then
it is the init caps snake case of the parameter name.
userAgent
-> User-Agent
lastModified
-> Last-Modified
@Post
Bar postIt(Foo payload, @Header("User-Agent") String userAgent); // explicit
@Post
Bar postIt(Foo payload, @Header String userAgent); // User-Agent
@Post
Bar postIt(Foo payload, @Header Collection<String> accept); // Accept
@Get
Bazz find(@Header String lastModified); // Last-Modified
@Header Map<String, ?>
We can use @Header
with a Map<String, ?>
, Map<String, String>
or Map<String, Object>
.
@Get("{type}")
List<Cat> searchByType(String type, String query, @Header Map<String, ?> myHeaders);
The generated code includes .header(myHeaders)
// GET {type}
@Override
public List<Cat> searchByType(String type, String query, Map<String,?> myHeaders) {
return clientContext.request()
.header(myHeaders)
.path("api").path("cats").path(type)
.queryParam("query", query)
.GET()
.list(Cat.class);
}
@QueryParam
We explicitly specify query parameters using @QueryParam
.
// Explicit query parameter order-by
@Get("/{bornAfter}")
List<Cat> findCats(LocalDate bornAfter, @QueryParam("order-by") String orderBy);
The generated code includes .queryParam("order-by", orderBy)
// GET /{bornAfter}
@Override
public List<Cat> findCats(LocalDate bornAfter, String orderBy) {
return clientContext.request()
.path(bornAfter)
.queryParam("order-by", orderBy)
.GET()
.list(Cat.class);
}
Implied query parameters
Query parameters can be implied by not being a path parameter. That is, if a method parameter does not match a path parameter then it is implied to be a query parameter.
The following 3 declarations are exactly the same with all 3 having
a query parameters for orderBy
@Get("/{bornAfter}")
List<Cat> findCats(LocalDate bornAfter, @QueryParam("orderBy") String orderBy);
@Get("/{bornAfter}")
List<Cat> findCats(LocalDate bornAfter, @QueryParam String orderBy);
@Post("/{bornAfter}")
List<Cat> findCats(LocalDate bornAfter, String orderBy); // orderBy implied as query parameter
We must explicitly use @QueryParam
when the query parameter
is not a valid java identifier. For example, if the query parameter includes a hyphen
then we must use @QueryParam
explicitly.
@QueryParam Map<String, ?>
We can use @QueryParam
with a Map<String, ?>
, Map<String, String>
or Map<String, Object>
@Post
void newCat(Cat cat, String myParam, @QueryParam Map<String,?> extraParams);
The generated code includes .queryParam(extraParams)
// POST
@Override
public void newCat(Cat cat, String myParam, Map<String,?> extraParams) {
clientContext.request()
.path("api").path("cats")
.queryParam("myParam", myParam)
.queryParam(extraParams)
.body(cat)
.POST()
.asVoid();
}
@BodyString
We can specify that a string parameter is a body using@BodyString
.
@Post("/stringbody")
List<Cat> addCats(@BodyString String body);
The generated code will be:
@Override
public List<Cat> addCats(String body) {
return clientContext.request()
.path("stringbody")
.body(body)
.GET()
.list(Cat.class);
}
@BeanParam
When we have a lot of query parameters or if we have query parameters
that are common to many endpoints then we look to use @BeanParam
.
We can create a bean and all the properties on the bean default to being
query parameters and annotate this with @BeanParam
.
public record Common(
Long firstRow,
Long maxRows,
String sortBy,
List<String> filters) { }
Use a record type or any type that has getter methods, record style getter methods or public fields.
public class Common {
public Long firstRow;
public Long maxRows;
public String sortBy;
public List<String> filters;
}
We annotate the method parameter with @BeanParam
@Get("search/{type}")
List<Cat> searchCats(String type, @BeanParam Common commonParams);
Generated code has queryParam()
for each of the properties:
// GET search/{type}
@Override
public List<Cat> searchCats(String type, Common commonParams) {
return clientContext.request()
.path("search").path(type)
.queryParam("firstRow", commonParams.firstRow())
.queryParam("maxRows", commonParams.maxRows())
.queryParam("sortBy", commonParams.sortBy())
.queryParam("filters", commonParams.filters())
.GET()
.list(Cat.class);
}
JAX-RS @BeanParam
Our @BeanParam is the same as JAX-RS @BeanParam except the properties default to being query parameters. With JAX-RS we need to explicitly annotate each of the properties. We can do this because we also have @Form and "Form beans".
BeanParam with @Header properties
The properties on a "bean" default to being query parameters. We put @Header on properties that are instead headers.
public record Common(
Long firstRow,
Long maxRows,
String sortBy,
String filter,
@Header("X-Mod")
String modification) { }
We then get the modification
value set as a header.
.header("X-Mod", commonParams.modification())
@Form
If a method has both @Post
and @Form
then the
method parameters default to be form parameters.
In the following example name, email and url all default to be form parameters.
@Form @Post("register")
void register(String name, String email, String url);
The generated code includes .formParam()
for name, email and url.
// POST register
@Override
public void register(String name, String email, String url) {
clientContext.request()
.path("register")
.formParam("name", name)
.formParam("email", email)
.formParam("url", url)
.POST()
.asVoid();
}
@FormParam
For the example above we could alternatively use explicit @FormParam
on each of the form parameters rather than @Form
. We then get:
@Post("register")
void register(@FormParam String name, @FormParam String email, @FormParam String url);
The expectation is that we most often would use @Form
because it reduces
"annotation noise" and that we will very rarely use @FormParam
. Potentially
we only use @FormParam if the parameter name includes hyphen or similar characters that
are not valid Java/Kotlin identifiers.
@FormParam Map<String, ?>
We can use @FormParam
with a Map<String, ?>
, Map<String, String>
or Map<String, Object>
.
@Put("{id}")
void register(UUID id, @FormParam Map<String, ?> params);
The generated code includes .formParam(params)
// PUT {id}
@Override
public void register(UUID id, Map<String,?> params) {
clientContext.request()
.path("api").path("cats").path(id)
.formParam(params)
.PUT()
.asVoid();
}
@Form "Form Beans"
In the case where we are posting a form with a lot of parameters we can define a bean with properties for each of the form parameters rather than have a method with lots of arguments.
public record RegisterForm(String name, String email, String url) { }
@Form @Post("register")
void register(RegisterForm myForm);
// POST register
@Override
public void register(RegisterForm myForm) {
clientContext.request()
.path("register")
.formParam("name", myForm.name())
.formParam("email", myForm.email())
.formParam("url", myForm.url())
.POST()
.asVoid();
}
"Form beans" are nice with large forms because they help de-clutter our code and the generated code takes care of putting the values into our bean properties so that we don't have to write.
This use of @Form is very similar to JAX-RS @BeanParam except that the
bean properties default be being form parameters. With JAX-RS we would put a @FormParam
on every property that is a form parameter which becomes a lot of annotation noise on a large form.
Form beans with @QueryParam, @Header properties
The properties on a "form bean" default to being form parameters. We put @QueryParam, @Header on properties that are instead query params, headers or cookies.
public record RegisterForm(
String name,
String email,
String url,
@QueryParam Boolean overrideFlag,
@Header String xModified) { }
The generated code includes queryParam()
and header()
for
those parameters:
// POST register
@Override
public void register(RegisterForm myForm) {
clientContext.request()
.path("register")
.formParam("name", myForm.name())
.formParam("email", myForm.email())
.formParam("url", myForm.url())
.queryParam("overrideFlag", myForm.overrideFlag())
.header("X-Modified", myForm.xModified())
.POST()
.asVoid();
}
@Client Java Module Setup
If using java modules with generated Client Interfaces, in the module-info.java
we need to:
- Add a requires clause for io.avaje.http.api
- Add a requires clause for io.avaje.http.client
- Add a provides clause for io.avaje.http.client.HttpClient.GeneratedComponent
Example module-info
import io.avaje.http.client.HttpClient.GeneratedComponent
module org.example {
requires io.avaje.http.api;
requires io.avaje.http.client
// you must define the fully qualified class name of the generated classes. if you use an import statement, compilation will fail
provides GeneratedComponent with org.example.GeneratedHttpComponent;
}
In the example above, org.example.GeneratedHttpComponent
is generated code typically found in
target/generated-sources/annotations
.
10K requests - Loom vs Async
The following is a very quick and rough comparison of running 10,000 requests using Async vs Loom.
The intention is to test the thought that in a "future Loom world" the
desire to use async()
execution with HttpClient reduces.
TLDR: Caveat, caveat, more caveats ... initial testing shows Loom to be just a touch faster (~10%) than async.
To run my tests I use Jex as the server (Jetty based) and have it running using Loom. For whatever testing you do you will need a server that can handle a very large number of concurrent requests.
The Loom blocking request (make 10K of these)
HttpResponse<String> hres = httpClient.request()
.path("s200")
.GET()
.asString();
The equivalent async request (make 10K of these joining the CompletableFuture's).
CompletableFuture<HttpResponse<String>> future = httpClient.request()
.path("s200")
.GET()
.async()
.asString()
.whenComplete((hres, throwable) -> {
...
});
10K requests using Async and reactive streams
Use .async()
to execute the requests which internally is using JDK
HttpClient's reactive streams. The whenComplete()
callback is invoked
when the response is ready. Collect all the resulting CompletableFuture
and wait for them all to complete.
Outline:
// Collect all the CompletableFuture's
List<CompletableFuture<HttpResponse<String>>> futures = new ArrayList<>();
for (int i = 0; i < 10_000; i++) {
futures.add(httpClient.request().path("s200")
.GET()
.async().asString()
.whenComplete((hres, throwable) -> {
// confirm 200 response etc
...
}));
}
// wait for all requests to complete via join() ...
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
10K requests using Loom
With Loom Java 17 EA Release we can use Executors.newVirtualThreadExecutor()
to return an ExecutorService that uses Loom Virtual Threads. These are backed
by "Carrier threads" (via ForkedJoinPool).
Outline:
// use Loom's Executors.newVirtualThreadExecutor()
try (ExecutorService executorService = Executors.newVirtualThreadExecutor()) {
for (int i = 0; i < 10_000; i++) {
executorService.submit(this::task);
}
}
private void task() {
HttpResponse<String> hres =
httpClient.request().path("s200")
.GET()
.asString();
// confirm 200 response etc
...
}
Caveat: Proper performance benchmarks are really hard and take a lot of effort.
Running some "rough/approx performance comparison tests" using Loom
build 17 EA 2021-09-14 / (build 17-loom+7-342)
vs Async for my environment
and 10K request scenarios has loom execution around 10% faster than async.
It looks like Loom and Async run in pretty much the same time although it currently looks that Loom is just a touch faster (perhaps due to how it does park/unpark). More investigation required.
Date: 2021-06
Build: 17 EA 2021-09-14 / (build 17-loom+7-342)
.
openjdk version "17-loom" 2021-09-14 OpenJDK Runtime Environment (build 17-loom+7-342) OpenJDK 64-Bit Server VM (build 17-loom+7-342, mixed mode, sharing)


You've been challenged to rock-paper-scissors by the smug bug! The rules are the classic rock paper scissors rules set with rock beating scissors, scissors beating paper, and paper beating rock. Click the start the match button to begin, and click on the option icons below the match area to make your choice of the trio (the default is rock). Once you've decided, hit the ready button and the winner of the match is revealed!
This game is a little more complicated than the guessing game, though not by much. The choice of the computer is completely random, so any perceived intelligence on the part of the computer is entirely in your head. The higher level of complexity in this one actually comes from tracking all the different statistics and deciding what the optimal structure was for the game. At first I was planning on implementing a 5 second timer, or something to that effect, but after various testing I opted just to let the player have control over when they are ready to proceed to the results.


New products pay off as Graham’s The Family Dairy posts sales hike
by Scott ReidGraham’s The Family Dairy has hailed its investment in product development and innovation for a hike in annual sales.
The Bridge of Allan-based milk and food producer described a 4.7 per cent year-on-year rise in sales to £109 million as “encouraging”.
At £2.2m, profit before tax was up on last year and the 80-year-old business also reported a “strong” underlying – earnings before interest, tax, depreciation and amortisation – performance of just over £4.6m.
The firm said its “clear focus on authentic family brand values and development of brand message”, as well as continued business innovation had paid off. There was total capital investment of £5.6m made in the past year.
Last year saw the successful launch of Graham’s Skyr, a Scandinavian-style cultured dairy product which is said to be naturally high in protein. Sales of the product to date have exceeded expectations, the firm noted. It is available across the UK, as well as now being exported to the Republic of Ireland, France and the UAE.
In March this year, the company launched its Goodness range, introducing a new low-calorie ice cream and flavoured cottage cheese. The ice cream developed for the UK market was in direct response to the low calorie and lower-in-sugar ice cream currently trending in the US. Graham’s claimed that customer interest has been “unprecedented”.
Proud
Robert Graham, managing director at Graham’s the Family Dairy, said: “As a third-generation family business, I am very proud to be celebrating the 80th year of the business that was started with 12 cows by my grandparents in 1939 at Airthrey Kerse in Bridge of Allan.
“We pride ourselves, not only on working hard to produce high quality and great tasting products, but also being dynamic and innovative to meet developing consumer trends that are very much aligned to dairy products.
“It is very important that we continue to grow margins in order to be able to continue to invest into the business and keep up this pace of innovation.”
He added: “New product development is a key priority for us to enable us to meet developing consumer trends for great tasting, naturally functional dairy products made with fresh Scottish milk. This clear focus has led to us investing £5.6m in the business this year alone.”
In February, the milk producer said it had entered into a record five-year partnership with discount supermarket chain Aldi.
The deal extended an existing partnership between the pair and will see fresh Scottish milk continue to be supplied to all 85 Aldi stores across Scotland. The deal is worth in the region of £55m.


With the election coming up in November and the COVID-19 pandemic causing disruptions, many groups and commmunities are increasing their focus on vote-by-mail options. While that increased focus is justified, that action alone is insufficient to protect the right to vote in the 2020 elections. Failure to ensure safe, accessible in-person voting risks further disenfranchising many Americans, especially those in marginalized groups. We believe that the expansion of voting by mail must be coupled with resources to address local operational gaps that will make voting in person increasingly difficult.
Due in large part to COVID 19, our election system is facing a critical shortage of poll workers to staff the polls in 2020. Recruiting poll workers, who work to ensure the in-person voting process operates safely and efficiently, is challenging even in normal times. Today, COVID-19 has exacerbated the difficulties typically associated with poll worker recruitment: a large proportion of poll workers tend to be senior citizens, a vulnerable population during this pandemic that will, with good reason, likely refrain from working the polls in November.
To address this issue, Carnegie Mellon University, in collaboration with the Voter Protection Corps, developed a “voting risk assessment” tool by collecting and analyzing public data to determine which counties in eight key states (Arizona, Florida, Michigan, North Carolina, Ohio, Pennsylvania, Texas, and Wisconsin) will need the most support in recruiting poll workers to ensure the right to vote. Though thorough poll worker recruitment will require a large-scale intervention from many organizations and governments across the country in this election, our tool analysis enables organizations to understand:
We provide a detailed explanation for each of the views included in the toolkit here: User Guide. Additionally, we provide some screenshots of how each of the pages look below. A detailed explanation of how this toolkit is provided in the detailed report.
| Data Source | Description | Year | Data |
|---|---|---|---|
| Election Administration and Voting Survey (EAVS) | Provides county-level election data about the resources, local characteristics, and infrastructure for U.S. elections. | 2016 | Link |
| The Cooperative Congressional Election Study (CCES) | Provides information about political attitudes and voter election experience | 2016 | Link |
| American Community Surveys (ACS) | Provides community characteristics of U.S. residents. | 2018 | Link |
| Metric | Indicator | Definition (County Level) | Data Sources |
|---|---|---|---|
| Demand Risk | In-Person Voters | Number of persons who vote in-person | EAVS |
| Inactive Voters | Number of inactive voters (who would need to go in person to reactivate their registration) | EAVS | |
| Resource Supply Risk | Voters per Location | Number of voters per polling location | EAVS |
| Voters per Machine | Number of voters per voting machine | EAVS | |
| Voters per Poll-worker | Number of voters assigned per poll-worker | EAVS | |
| Wait Times | Time waited to cast the vote | CCES Survey Data | |
| Priority Population Risk | Black and Latino Population | Number of Black and Latino voters | Census |
| Senior Citizens | Number of senior citizen voters (60+) | Census | |
| Poll Worker Recruiting Risk | Recruiting Difficulty | Difficulty in Recruiting (1 to 5) | EAVS |
| Senior Poll Workers | Number of Poll-workers who were seniors (60+) | EAVS |
Kaila Gilbert Carnegie Mellon University
Hemank Lamba Carnegie Mellon University
Jessica Toth Carnegie Mellon University
Bob LaRocca Voter Protection Corps
Rayid Ghani Carnegie Mellon University
Quentin Palfrey Voter Protection Corps


Latest Posts
-
Compact Schemes for the Poisson Equation
This notebook demonstrates how to solve Poisson’s equation using Compact finite-difference schemes.
-
APS-Division of Fluid Dynamics
73rd Annual Meeting of the APS Division of Fluid Dynamics
-
Pseudo-spectral method for 2D Turbulence
Mathematical Formualtion
-
My First Post
Code Snippets