I am migrating our dialog flow agent to use V2 API. Our V1 implementation uses Java client library from dialog-flow(api-ai). Our web service receives the request on webhook endpoint which is configured to invoke 'doWebook' method.
Below is the V1 implementation where I use AIWebhookRequest and Fulfillment
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Fulfillment output = new Fulfillment();
doWebhook(gson.fromJson(request.getReader(), AIWebhookRequest.class), output);
response.setCharacterEncoding(RESPONSE_CHARACTER_ENCODING);
response.setContentType("application/json");
gson.toJson(output, response.getWriter());
}
/** handle the actions passed by Google Home intents **/
protected void doWebhook(AIWebhookRequest input, Fulfillment output) {.....}
I am trying to utilize google-cloud-dialogflow-v2 java library now with the following changes
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Fulfillment output = new Fulfillment(); // ** This is still V1, What could I use from V2 here??**
doWebhook(gson.fromJson(request.getReader(), *WebhookRequest*.class), output);
response.setCharacterEncoding(RESPONSE_CHARACTER_ENCODING);
response.setContentType("application/json");
gson.toJson(output, response.getWriter());
}
/** handle the actions passed by Google Home intents **/
protected void doWebhook(*WebhookRequest* input, *WebhookResponse* output) {.....}
My question is on the line
Fulfillment output = new Fulfillment(); // This is still V1, What could I use from V2 here??
Related
This question was already asked, however since then all answers (that I could found) are no longer valid.
Essentially I want to implement a website with Vaadin (V23), that communicates with a WebApp via POST requests that is running on another server (physically). To do it, I want to create separate Servlet that would handle the communication (receiving side) with another Server. Let's say, this is not implemneted version:
#WebServlet(urlPatterns = "/communication", name = "QuizServlet", asyncSupported = true)
public class QuizServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
}
The problem is however, that I always get redirected to default dispatcher Servlet, and it seems, regardless of what I do:
SpringVaadinServlet was deprecated and no longer exists, extending VaadinServlet does not work.
Changing mappings in properties (vaadin.url-mapping=) also does not work, I just get redirected to this new mapping in all cases.
Trying to do servlets on separate ports yields same redirection on all ports, even if explicitly registering my custom Servlet on the Connector, with separate Sevice (WebMvcConfigurer Tomcat configuration). Answer from this post, also too old.
Registering servlet directly also does not do anything (by implementing WebApplicationInitializer).
There for the question, how to make use of two different servlets with new Vaadin 23 and Spring Boot 2.7.1?
I have found some kind of a solution to my problem. Namely on startup of my BootAplication, I am also starting the second separate Tomcat server that uses my custom Servlet :
#Service
public class QuizServer {
private final Log log = LogFactory.getLog(QuizServer.class);
#PostConstruct
public void startServer() throws IOException, LifecycleException {
start();
}
private void start() throws IOException, LifecycleException {
Tomcat tomcat = new Tomcat();
String contextPath = "/";
String appBase = new File(".").getAbsolutePath();
Context ctx = tomcat.addContext(contextPath, appBase);
Tomcat.addServlet(ctx, "quizServlet", new QuizServlet());
ctx.addServletMappingDecoded("/*", "quizServlet");
tomcat.setPort(8085);
tomcat.start();
tomcat.getConnector();
log.info("Quiz server started");
}
}
#WebServlet(urlPatterns = "/*", name = "quizServlet", asyncSupported = true)
public class QuizServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Test");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
}
It is a bit crude though, since ideally, it shouldn't require a separate server.
I'm New to security & JAVA and I need to implement token follow of OAuth2, this is the exact flow which I need to implement (if there is some library which can help it's great )
http://tutorials.jenkov.com/oauth2/authorization-code-request-response.html
How can I achieve it with JAVA, I want to use some library that provide this functionality. the token flow should be against the UAA but any other similar example will be very helpful.
i've found this example but not sure how to use/test it E2E with UAA
Postman will be very helpful to simulate it...
https://developers.google.com/api-client-library/java/google-oauth-java-client/oauth2
UAA context
https://github.com/cloudfoundry/uaa
I would suggest you Spring as the most popular framework for building web apps in Java. It has Spring Security module that can facilitate developing OAuth 2.0 clients as well as resource servers, as shown here or here.
For a detailed explanation of the OAuth 2.0 flow, visit RFC 6749 Specification. Regarding a step by step solution, you ought to see some tutorials such as this article explaining how to create a Spring REST API using OAuth 2.0. This article goes through code as well as creating Postman requests. With regards to mocking/tests, I've previously created a test suite for the OAuth 2.0 using TestNG and Mockito.
The more you develop and research, the more you shall find ways of improving or rather change the way you design your code. That said if you really want to abide by the OAuth 2.0 flow, you should properly understand the flow (which can be relatively vague at times) in the RFC 6749 link.
Here is the Google API clinet library sample. Try this if it helps
public class ServletSample extends AbstractAuthorizationCodeServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// do stuff
}
#Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(),
new NetHttpTransport(),
new JacksonFactory(),
new GenericUrl("https://server.example.com/token"),
new BasicAuthentication("s6BhdRkqt3", "7Fjfp0ZBr1KtDRbnfVdmIw"),
"s6BhdRkqt3",
"https://server.example.com/authorize").setCredentialDataStore(
StoredCredential.getDefaultDataStore(
new FileDataStoreFactory(new File("datastoredir"))))
.build();
}
#Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
public class ServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet {
#Override
protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
throws ServletException, IOException {
resp.sendRedirect("/");
}
#Override
protected void onError(
HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
throws ServletException, IOException {
// handle error
}
#Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(),
new NetHttpTransport(),
new JacksonFactory(),
new GenericUrl("https://server.example.com/token"),
new BasicAuthentication("s6BhdRkqt3", "7Fjfp0ZBr1KtDRbnfVdmIw"),
"s6BhdRkqt3",
"https://server.example.com/authorize").setCredentialDataStore(
StoredCredential.getDefaultDataStore(
new FileDataStoreFactory(new File("datastoredir"))))
.build();
}
#Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2 contains sample code for performing oauth2 using Spring Security.
I have written the following code in service and post methods
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter p = response.getWriter();
p.println("<html><body>");
p.println("<form action = roomlog2 method = post>");
p.println("<input type = submit value = back>");
p.println("</form>");
p.println("</body></html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect("homepage.html");
}
But when i executed the code and click the back button the post method is not executing. I am getting following exception
java.lang.NumberFormatException: null
why the post method not redirecting to the "homepage.html"?why i am getting the exception?Kindly someone can tell me the error.
Just remove your implementation of the service() method, or have it call super.service(). That's how doPost() gets called. At present you're not calling it at all.
I would like to upload a string to a server in java. I would not like to just upload a file I would like to upload a string
String toupload = "Cheese"; Upload(toupload);
like this
You can upload it using both POST method, and GET methods:
If you use the GET method: you pass the string in the url.
ex: localhost:8080/yourwebproject/yourservlet?nameofyourstring=itsvalue
And then in your servlet you can do something like:
public myServlet extends HttpServlet(HttpServletRequest request, HttpServletResponse response)
public myServlet() {
super();
}
/*This method will be called by your web-container if you used the get method..*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
//here we go
String str = request.getParameter("nameOfyourString");
}`
}
If you use the POST method, you have to implement the doPost with same logic..
How do I broadcast messages from only one client to another with Atmosphere (Meteor)?I have currently this implementation based on meteor tutorial
#Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
Meteor.build(req).addListener(new AtmosphereResourceEventListenerAdapter());
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException {
String body = req.getReader().readLine().trim();
//some DAO lookups - here I would like to say I want to broadcast only to concrete client
BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class, "/*").broadcast(UserDAO.getInstance().getUser(name));
}
Here is the Atmosphere FAQ on their wiki: https://github.com/Atmosphere/atmosphere/wiki/Creating-private-channel-of-communication-between-Browsers
Another solution I believe : for adressing only one client, you don't need to broadcast, you may just do this:
try
{
r.getResponse().write(message);
}
catch(IllegalStateException e)
{
logger.error("Could not send message through atmosphere " + userId);
}
where r is the resource that you can memorize in your program.
BroadcasterFactory.getDefault().lookup(atmosphereResource.uuid()).broadcast('something');