Spring Integration : int-http:inbound-gateway with url Path Variables - java

I am trying to test an Inbound http gatway using Spring Integration int-http:inbound-gateway:
<int-http:inbound-gateway id="correlateOutgoingMessage"
supported-methods="POST" request-channel="toOutCorrelator"
reply-channel="fromOutCorrelator" view-name="/correlateOutgoingMessage"
path="/correlateOut/{origin}/{msgtype}/{priority}"
reply-timeout="50000">
<int-http:header name="origin" expression="#pathVariables.origin" />
<int-http:header name="msgtype" expression="#pathVariables.msgtype" />
<int-http:header name="priority" expression="#pathVariables.priority" />
</int-http:inbound-gateway>
My Web.xml :
<servlet>
<servlet-name>correlateOut</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/intg-schema.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>correlateOut</servlet-name>
<!-- controler/* -->
<url-pattern>/correlateOut/*</url-pattern>
</servlet-mapping>
Using the RestTemplate I am trying to make a POST request to the gateway:
The
uri = "http://localhost:8080/test/correlateOutgoingMessage/{origin}/{msgtype}/{priority}"
String origin = "xxxx";
Integer msgtype = 2333;
Integer priority = 2;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<?> request = null;
ResponseEntity<String> httpResponse = null;
request = new HttpEntity<Object>(messageContent);
httpResponse = template.exchange(uri, HttpMethod.POST, request,
String.class, getUrlParams(origin, msgtype, priority));
I am alway getting NOT FOUND 404, would you any please give me some hints?
Thank you very much!

First of all you should show the uri which you use to send HTTP request.
From other side if you map servlet to the /correlateOut/* you must not to use it in the target mapping, because all other endpoints are under that context.
So, your path should be path="{origin}/{msgtype}/{priority}"

Related

The request sent by the client was syntactically incorrect - Spring

I want to create Spring REST method with generic parameters.
This method will be calling by Angular http post method.
When i deploy my app i've got error:
The request sent by the client was syntactically incorrect.
My Java Class with Spring REST method:
#RestController
#RequestMapping("/store")
public class TestController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class.getName());
#RequestMapping(value = "/order", method = RequestMethod.POST)
public ResponseEntity handleOrder(#RequestBody Class<?> dataType,
#RequestBody Class<?> orderType, #RequestBody Class<?>[] dataArr) {
LOGGER.debug("TEST" + dataType + " " + orderType + " " + dataArr);
return new ResponseEntity(HttpStatus.OK);
}
};
My JavaScript file with Angular post method:
var cars = ["Saab", "Volvo", "BMW"];
$http.post('/rest/store/order', {
dataType: "Client",
orderType: "Simple",
dataArr: cars }
);
My servlet-mapping in web.xml file:
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Question: How to resolve this error?

Writing to JSONobject through Restful Webservice

I am learning how to use Restful Webservice, i dont really know if my approach is good or totally wrong, so bear with me
I got a project structure, which look like this :
I want to by calling the right URL, save the string accordingly in Datum.Json
Here is my Java Class of the WebService :
package Rest;
#Path("/calendar")
public class CalendarTest {
public List<Date> dates;
#GET
#Path("/dates/get/")
#Produces(MediaType.APPLICATION_XML)
public List<Date> getUsers(){
return dates;
}
#PUT
#Path("/dates/put/{param1}+{param2}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void updateDate(#PathParam("param1") String city, #PathParam("param2") String date) throws IOException {
JSONObject obj = new JSONObject();
obj.put("City", city);
obj.put("Date", date);
try (FileWriter file = new FileWriter("/RestTest/Datum.json")) {
file.write(obj.toJSONString());
System.out.println("Successfully Copied JSON Object to File...");
System.out.println("\nJSON Object: " + obj);
}
}
}
I tested the localhost, it works fine (i can open the form.html with my localhost)
My web.xml file :
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>Rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<security-constraint>
</security-constraint>
</web-app>
But when i tried the URL http://localhost:8080/RestTest/rest/calendar/dates/put/Berlin+20-12-2019
It says the method not allowed.
Can anyone explain to me why ?
It's because when you are typing in a URL in your browser, it sends a HTTP GET request by default, so it throws an error because you do not have a GET request handler for that URL, you only have a handler for a PUT request.
You can't change the browser's default request type. What you have to do is send the request yourself using something like jQuery in your frontend / javascript.
How to send a PUT/DELETE request in jQuery?
You could use the ajax method:
$.ajax({
url: '/rest/calendar/dates/put/Berlin+20-12-2019',
type: 'PUT',
success: function(result) {
// Do something with the result
}
});

Spring : No mapping found for HTTP request

I strangely have this problem :
[04/07/14 11:31:09:009 CEST] WARN servlet.PageNotFound: No mapping found for HTTP request with URI [/datapine-backend/heroku/resources] in DispatcherServlet with name 'rest'
However, I checked the logs and my method is already mapped!
annotation.RequestMappingHandlerMapping: Mapped "{[/heroku/resources/],methods=[POST],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.datapine.heroku.HerokuController.provision(net.sf.json.JSONObject)
This my method :
#Controller
public class HerokuController {
#RequestMapping(value = "/heroku/resources/", method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> provision(#RequestBody JSONObject body){
System.out.println("called! \n");
JSONObject response = new JSONObject();
response.put("id", 555);
response.put("message", "Provision successful!");
return new ResponseEntity<String>(response.toString(),HttpStatus.OK);
}
This is my web.xml
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/heroku/*</url-pattern>
</servlet-mapping>
and this is the rest-servlet.xml :
<beans:import resource="classpath:spring-properties-loader.xml"/>
<context:component-scan base-package="com.datapine.heroku" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
</beans:beans>
what can be the problem?
thanks.

How to use #RequestMapping headers?

I am studying springmvc. When I use #RequestMapping(value="/helloWorld", headers = "content-type=text/*") and connect to http://localhost:8080/SpringMVC_10100/helloWorld, the following is output in the console:
WARN
org.springframework.web.servlet.PageNotFound
- No matching handler method found for servlet request: path '/helloWorld',
method 'GET', parameters
map[[empty]]
My code is:
#Controller
public class HelloWordController {
private Logger logger = LoggerFactory.getLogger(HelloWordController.class);
#RequestMapping(value="/helloWorld", headers = "content-type=text/*")
public ModelAndView helloWorld() {
logger.debug("jin ru le");
logger.info("The helloWorld() method is use");
ModelAndView view = new ModelAndView();
view.setViewName("/helloworld");
return view;
}
}
web.xml is
<servlet>
<description>This is Spring MVC DispatcherServlet</description>
<servlet-name>SpringMVC DispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>SpringContext</description>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC DispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Why?
Its most likely the case that /helloworld is not inside the path configured for your dispatcher servlet
e.g. If i have a servlet configured like so:
<servlet>
<servlet-name>BMA</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BMA</servlet-name>
<url-pattern>/bma/*</url-pattern>
</servlet-mapping>
And i have a controller configured like so:
#RequestMapping(value = "/planner/plan/{planId}/delete", method = RequestMethod.GET)
public ModelAndView deletePlanConfirm(HttpServletRequest request,
#PathVariable("planId") Long planId) {}
Then the request in browsder would be:
http://localhost:8080/bma/planner/plan/1223/delete
Edit:
Also if you have content-type header narrowing on your handler, make sure that content-type haeder is sent in your request.
In the below annotation remove the headers:
#RequestMapping(value="/helloWorld", headers = "content-type=text/*")
to:
#RequestMapping(value="/helloWorld", method = RequestMethod.GET)
or to:
#RequestMapping(value="/helloWorld")
should make it work.

SEAM - get url of base65 authentication

I have this config in my components.xml:
<web:authentication-filter url-pattern="/resource/rest/*" auth-type="basic"/>
<security:identity authenticate-method="#{basicAuthenticator.login}"/>
Well, my basicAuthenticator is a Stateless seam component where i have that login method which returns true/false depending on credentials.
I do really want to find the host (url adress) of the request.
Of course i can use ExternalContext like:
#In(value = "#{facesContext.externalContext}", required = false)
private ExternalContext externalContext;
but it gives me null because i have no jsf here...
Do you know any other way?
Thanks.
Cristian,
Because ServletFilter will always be called before FacesServlet, you will always get null.
So do not use
private #In FacesContext facesContext;
anymore when using Servlet Filter.
Solution: well, it can not be The best solution but it solves what you want to do
Create a CustomAuthenticationFilter as follows
#Scope(APPLICATION)
#Name("org.jboss.seam.web.authenticationFilter")
#Install(value = false, precedence = BUILT_IN)
#BypassInterceptors
#Filter(within = "org.jboss.seam.web.exceptionFilter")
public class CustomAuthenticationFilter extends org.jboss.seam.web.AbstractFilter {
/**
* Because of some private methods defined in AuthenticationFilter
* do Ctrl + C / Ctrl + V All of source code of AuthenticationFilter
*
* Except authenticate method which is shown bellow
*/
private void authenticate(HttpServletRequest request, final String username) throws ServletException, IOException {
new ContextualHttpServletRequest(request) {
#Override
public void process() throws ServletException, IOException, LoginException {
Identity identity = Identity.instance();
identity.getCredentials().setUsername(username);
try {
identity.preAuthenticate();
/**
* Yes, THE SAME LOGIC performed by authenticate-method must goes here
*/
/**
* Do not use #In-jection here
*
* Use context lookup instead
* For instance, UserService userService = (UserService) Contexts.lookupInStatefulContexts("userService");
*/
identity.postAuthenticate();
} finally {
// Set password to null whether authentication is successful or not
identity.getCredentials.setPassword(null);
}
}
}.run();
}
}
Now overrides default AuthenticationFilter in /WEB-INF/componets.xml
<web:rewrite-filter view-mapping="/resource/rest/*"/>
<component name="org.jboss.seam.web.authenticationFilter" class="br.com.ar.seam.CustomAuthenticationFilter">
<property name="urlPattern">/resource/rest/*</property>
<property name="authType">basic</property>
</component>
And To enable restURL do as follows
web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--HERE GOES NON-REST INTERCEPTED URL-->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.seam</url-pattern>
</servlet-mapping>
<!--HERE GOES REST INTERCEPTED URL-->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Now, let's suppose you want to call /resource/rest/user which matchs restURL servlet-mapping. In /WEB-INF/pages.xml declare
<page view-id="<VIEW_ID_GOES_HERE>">
<rewrite pattern="/resource/rest/user"/>
<rewrite pattern="/resource/rest/{userId}"/>
<!--userId comes from pattern shown above-->
<param name="userId" value="#{userService.userId}"/>
</page>
To avoid FacesServlet intercept any client-side resource such as css, javaScript and images files, you can define
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
Which does not apply JSF lifecycle. Make sure put Seam Resource Servlet above FacesServlet declaration.

Categories