WSO2 MSF4J receive large data in #Post - rest

We are using wso2 microservice engine as middleware between WSO2 EI and DB. The target chain MQ->WSO EI->msf4j->DB. DTO which is transfered - formatted xml string which basically shouldn't be parsed till msf4j layer. So, for all this is just string. Sometimes this is a big string.
Our code
#Path("/accountdao")
public class AccountDaoService implements Microservice {
#POST
#Path("/getbyparam")
#Produces(MediaType.TEXT_PLAIN)
public String getAllAccounts(#QueryParam("commandText") String commandText) {
Previously we tested it in GET's style calls, I mean smth like
URL url = new URL(serverURL + requestURL + "/?commandText=" +
URLEncoder.encode(request,"UTF-8"));
Cause in all other styles, using let's say HttpClient from commons, we didn't receive data in commandText.
And I've found, that I don't know how to pass large data using SoapUI or just clear java client..
With small text blocks(like 200-300 chars) is all ok, but with 6k lenght this is already problem.
Is it possible to handle in msf4j large strings or we should use for it smth else?
thanks.
ps
probably we should use #FormParam & multipart/form-data?
UPDATE 1
<payloadFactory media-type="xml">
<format>
<uri.var.commandText xmlns="">$1</uri.var.commandText>
</format>
<args>
<arg evaluator="xml" expression="get-property('uri.var.commandText')"/>
</args>
</payloadFactory>
<call blocking="true" description="">
<endpoint key="microserviceEP"/>
</call>
and microservice code
#POST
#Path("/getclientcontract")
#Produces(MediaType.TEXT_PLAIN)
public String getClientContract(#Context Request request) {
List<ByteBuffer> fullMessageBody = request.getFullMessageBody();
StringBuilder sb = new StringBuilder();
for (ByteBuffer byteBuffer : fullMessageBody) {
sb.append(StandardCharsets.UTF_8.decode(byteBuffer).toString());
}
String commandText = sb.toString();
is it ok, or there is possible more correct way?

Related

How to set char encoding to utf-8 in JAX-RS Jersey 2.0 Response

I`ve written a RESTService that creates a PDF and returns it via Response Object.
Here is my Client:
final Response response = target.request(MediaType.APPLICATION_OCTET_STREAM).post(Entity.entity(building, MediaType.APPLICATION_JSON + ";charset=utf-8"));
int responseCode = response.getStatus();
String fileName = Response.getHeaderString("fileName");
And here is the important part of my Web Service method:
return Response.ok(report, MediaType.APPLICATION_OCTET_STREAM).header("fileName", reportName).build();
My problem is that the umlauts of my filename are just erased:
So for example, if the fileName is : "Gebäude2_2014" the Client will receive "Geb ude2_2014".
Anybody an idea?
You should be able to use the JAX-RS #Produces in your web service controller and force the UTF-8 encoding. This should fix your issue.
here an example:
#Path("/ws/v1")
#Produces("\"application/json\";charset=utf-8")
public class Documents extends AbstractController {
#GET
#Path("/documents/{id}")
public Response show(#Context UriInfo uri, #PathParam("id") String id) {
...
return Response.ok(report, MediaType.APPLICATION_OCTET_STREAM).header("fileName", reportName).build();
}
}
I've tried to pass a header in response with MediaType.APPLICATION_OCTET_STREAM in my project, and your "Gebäude2_2014" String is read correctly.
In my project all source files are encoded with UTF-8.

How to fix my url in spring framework

I am working with Spring MVC3.2 and I have a registration form(http://my-server.com:8080/tracks/apks). Users post it to the server and the server will return error message when validation fails. But I got the error message from the server, the URL was different from what I wanted. Here is my code:
Web.xml
<servlet-mapping>
<servlet-name>tracks</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
applicationContext.xml
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
#Controller
#RequestMapping("/apks")
public class ApkController {
#RequestMapping()
public ModelAndView index() {
Map<String, Object> modelMap = new HashMap<String, Object>();
modelMap.put("menus", AdminService.getMenus("apks"));
return new ModelAndView("apks", "model", modelMap);
}
#RequestMapping(value = "/insert", method = RequestMethod.POST)
public ModelAndView uploadApk(ApkInfo apkInfo, BindingResult bindingResult) {
Map<String, Object> modelMap = new HashMap<String, Object>();
modelMap.put("menus", AdminService.getMenus("apks"));
if (!fileExists(apk.getFileName())){
modelMap.put("message", message);
}
//Do something
return new ModelAndView("apks", "model", modelMap);
}
After calling uploadApk, I expected http://my-server.com:8080/tracks/apks but The returned URL was http://my-server.com:8080/tracks/apks/insert.
What do I do to fix it?
Thanks in advance.
Couple of observation.
In your web.xml, do you specify context-paran, the servlet tracks and the listener?
Is context:component-scan enabled in your spring configuration file?
Use requestMapping at method level to map request to specific method.
What does 'The returned URL' mean?
You should access 'http://my-server.com:8080/apks/insert' to call 'uploadApk' method
cause you have
#RequestMapping("/apks")
on your controller and
#RequestMapping(value = "/insert", method = RequestMethod.POST)
on your 'uploadApk' method.
How did you call the 'uploadApk' method?
I think that you should explain about it more to get an appropriate answer.
Since the url-pattern of servlet-mapping in your web.xml is '/',
you should remove '/tracks' in your url.
'tracks' is just a servlet name and not a servlet path.
So if you access to /tracks/apks/insert then you will got an 404 error.
Access to /apks/insert instead.
I guess that you may want a redirection after calling 'uploadApk' method
cause you attached 'redirect' tag on your question and used the word 'returned URL'. (Right?)
If my guess is right and you want to redirect the browser, then see SpringMVC 3.2 Redirect View docs.
Use below codes to redirect.
return new RedirectView("url-you-want");
or
return "redirect:url-you-want"

Spring MVC Restful App: Redirect a form result to another page

I'm new to Spring MVC Restful.
Suppose I have index.jsp which forwards user to a form page where user could submit a term to search. I catch the term with a POST handler method, and then do some calculation and hope to redirect the result to be used at another page (/WEB-INF/jsp), for example, we say build a graph based on the result. The problem is how to gather the results and redirect the URL at the same time.
The Controllers like below:
#RequestMapping(value="/termForm", method = RequestMethod.GET)
public ModelAndView setupForm() {
Term termClass = new Term();
return new ModelAndView("term", "command", termClass);
}
#RequestMapping(value="/getTerm", method=RequestMethod.POST)
public String getTerms(#ModelAttribute("term") Term term, BindingResult result)
{
String label = term.getTerm();
//doing some calculation to term here
result = ....
return "redirect:"+ "graphPage.jsp";
}
By searching, I found that Spring View Resolver only could process the redirected jsp under root directory (as same with index.jsp). In this case, the "result" seems not accepted by "graphPage". I also included UrlBasedViewResolver in XXX-servlet.xml as following:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
Sorry for the long question, please give any hint to do this. Thanks a lot.
There are two parts of my question. One is redirecting POST method to another page, graphPage.jsp. Since we go to graph, we need the data from POST method as well to create graph. This is the other concern. Hope it's clear. I already solved the first one by adding a handler method, see below. But how to package the result and pass it to Graph.jsp? Thanks
#RequestMapping(value="/graphPage", method=RequestMethod.GET)
public String showGraph()
{
return "graphPage";
}
You will get a better controll over the redirect if you use the RedirectView instead of the String. See this example.
#Contoller
#RequestMapping("/your")
public class YourController
#RequestMapping(value="/getTerm", method=RequestMethod.POST)
public ModelAndView getTerms(#ModelAttribute("term") Term term, BindingResult result) {
...
return new ModelAndView(new RedirectView("/your/other", true));
}
#RequestMapping(value="/other", method=RequestMethod.POST)
public String otherMethod() {...}
}
But maybe you asked something different, then please rewrite your question. It is very hard to understand what your problem is./
BTW. test that you can request your "graphPage" directly

How to get parameters name and value in RequestHandler of JAX-RS based Service in CXF

I am creating a JAX-RS based web service in CXF and I want to get the parameters passed to the method in the RequestHandler registered as a <jaxrs:provider>.
I want the parameter name and corresponding value in the handler and here is my code:
public class SampleRequestHandler implements RequestHandler {
#Override
public Response handleRequest(Message arg0, ClassResourceInfo arg1) {
OperationResourceInfo resourceInfo = arg0.getExchange().get(OperationResourceInfo.class);
String name = resourceInfo.getMethodToInvoke().getName();
return null;
}
}
My JAX-RS based service:
#Service("bookService")
#Path("/bookstore")
public class BookStore {
#POST
#Path("/books")
#Produces({ "application/xml" })
#Consumes({ "application/xml" })
public Book addBook(Book book) {
return book;
}
}
and my beans.xml where I have registered the handler and restful service:
<context:component-scan base-package="com.tutorial.cxf.jaxrs.service"/>
<bean id="sampleHandler" class="com.tutorial.cxf.jaxrs.interceptors.SampleRequestHandler"/>
<jaxrs:server id="restContainer" address="/">
<jaxrs:serviceBeans>
<ref bean="bookService"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="sampleHandler"/>
</jaxrs:providers>
</jaxrs:server>
Anybody already manage this case?
I had the same issue when trying to take the method with:
List<Parameter> params = ori.getParameters();
It only returns the parameter's name (the one declared in the method) but not the values.
The official CXF documentation shows only a little about it, but as explained you can always take the QUERY_STRING value of the message and parse it.
You can do something like this in your handler/filter:
String queryString = (String) arg0.get(Message.QUERY_STRING);
MultivaluedMap<String, String> queryMap = JAXRSUtils.getStructuredParams(queryString, "&", false, false);
and after loop over the queryMap collection. The map will contains all of your query parameters, even those who are not declared in the Rest method of your BookStore class.

extracting the complete envelope xml from MessageContext

I have an interceptor like this:
public class WebServiceInterceptor extends EndpointInterceptorAdapter {
#Inject
private Jaxb2Marshaller myJaxb2Marshaller;
#Inject
private WebServiceHistoryDao webServiceHistoryDao;
#Override
public boolean handleRequest(MessageContext messageContext, Object endpoint)
throws Exception {
Source payloadSource = messageContext.getRequest().getPayloadSource();
Object unmarshaled = myJaxb2Marshaller.unmarshal(payloadSource);
//EXTRACT XML HERE
//is there a better way than this:
String extractedXml = myJaxb2Marshaller.marshal(unmarshaled);
return true;
}
}
How can i extract the whole xml of envelope (for logging purposes - to write it to the DB)
You don't need to write one, there's an existing one in the API - SoapEnvelopeLoggingInterceptor. See the javadoc.
SOAP-specific EndpointInterceptor that logs the complete request and response envelope of SoapMessage messages. By default, request, response and fault messages are logged, but this behaviour can be changed using the logRequest, logResponse, logFault properties.
If you only need to see the payload, rather than the entire SOAP envelope, then there's PayloadLoggingInterceptor.