Is there a way to add a filter/interceptor to static resources served from META-INF/resources?
I seem have tried all the possible options: #ServerResponseFilter, ContainerResponseFilter,WriterInterceptor however all these functions are called only for #Path or #Route...
Is there anything similar to #RouteFilter but for response?
Those are the only ones available:
public interface ClientRequestFilter {
void filter(ClientRequestContext requestContext) throws IOException;
}
public interface ClientResponseFilter {
void filter(ClientRequestContext requestContext,
ClientResponseContext responseContext) throws IOException;
}
public interface ContainerRequestFilter {
void filter(ContainerRequestContext requestContext) throws IOException;
}
public interface ContainerResponseFilter {
void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException;
}
public interface ReaderInterceptor {
Object aroundReadFrom(ReaderInterceptorContext context)
throws java.io.IOException, javax.ws.rs.WebApplicationException;
}
public interface WriterInterceptor {
void aroundWriteTo(WriterInterceptorContext context)
throws java.io.IOException, javax.ws.rs.WebApplicationException;
}
You could try with ClientResponseFilter and see:
In the Client API, a ClientRequestFilter is executed as part of the
invocation pipeline, before the HTTP request is delivered to the
network.
ClientResponseFilter is executed upon receiving a server response,
before control is returned to the application.
https://quarkus.io/specs/jaxrs/2.1/index.html#filters_and_interceptors
There seem to be nothing built-in to modify the response of a static content for now but nothing stops you from serving content in a dynamic way:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
#Path("/")
#Produces(MediaType.TEXT_HTML)
public class FrontendController {
#GET
public Response index() throws IOException {
try (var index = getClass().getResourceAsStream(FrontendConstants.INDEX_RESOURCE)) {
if (index == null) {
throw new IOException("index.html file does not exist");
}
//modify index
return Response
.ok(index)
.cacheControl(FrontendConstants.NO_CACHE)
.build();
}
}
#GET
#Path("/{fileName:.+}")
public Response staticFile(#PathParam("fileName") String fileName) throws IOException {
try (var file = FrontendController.class.getResourceAsStream(FrontendConstants.FRONTEND_DIR + "/" + fileName)) {
if (file == null) {
return index();
}
var contentType = URLConnection.guessContentTypeFromStream(file);
return Response
.ok(
new String(file.readAllBytes(), StandardCharsets.UTF_8),
contentType == null ? MediaType.TEXT_PLAIN : contentType
)
.cacheControl(FrontendConstants.NO_CACHE)
.build();
}
}
}
Related
I'm trying to set the SameSite attribute of the JSESSIONID cookie in our JHipster gateway, and upon trying to verify in Chrome, there is nothing showing up under the SameSite column for it.
Possibly of note: we're currently not deployed and running the application locally on HTTP (a localhost address). Running in TLS mode also has the same problem, however.
These are two things I've tried in order to get this working:
The second approach from the first answer here How to enable samesite for jsessionid cookie - a filter that is used in JHipster's SecurityConfiguration.java file in the configure() method.
import java.io.IOException;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
public class SameSiteFilter implements javax.servlet.Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
addSameSiteCookieAttribute((HttpServletResponse) response); // add SameSite=strict cookie attribute
}
private void addSameSiteCookieAttribute(HttpServletResponse response) {
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE);
boolean firstHeader = true;
for (String header : headers) { // there can be multiple Set-Cookie attributes
if (firstHeader) {
response.setHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
firstHeader = false;
continue;
}
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; %s", header, "SameSite=Strict"));
}
}
#Override
public void destroy() {
}
}
A CookieSerializer which we got from an internal partner:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.DefaultCookieSerializer;
import org.springframework.session.web.http.CookieSerializer;
#Configuration
class CookieConfiguration {
#Bean
public static CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setSameSite("Lax");
return serializer;
}
}
Neither of these work. Is there something else we can try for this particular flavor of Spring?
In case you are using Tomcat (i.e. not WebFlux), the following configuration will add SameSite=strict to all cookies, including JSESSIONID:
#Configuration
public class SameSiteCookieConfiguration implements WebMvcConfigurer {
#Bean
public TomcatContextCustomizer configureSameSiteCookies() {
return context -> {
final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
cookieProcessor.setSameSiteCookies("strict");
context.setCookieProcessor(cookieProcessor);
};
}
}
I'm trying to work out a simple web app with angular as the front end and Spring Boot as the back end. My pre-flight request succeeds and I receive a valid token, however when trying to make a subsequent request to a route I get a 404. When I try to curl the url I get a 500 with the message "Missing or invalid authorization header" which seems to me to be saying that the route does indeed exist and is listening, but something else is wrong.
First of all the Typescript. Here is my login.component.ts
import { Component } from "#angular/core";
import { Observable } from "rxjs/index";
import { LoginService } from "../services/login.service";
#Component({
selector: "login",
templateUrl: "./login.component.html"
})
export class Login {
private model = {"username": "", "password": ""};
private currentUserName;
constructor (private loginService: LoginService) {
this.currentUserName = localStorage.getItem("currentUserName");
}
public onSubmit() {
console.log("submitting");
this.loginService.sendCredential(this.model).subscribe(
data => {
console.log(data);
localStorage.setItem("token", data);
console.log("Setting token");
this.loginService.sendToken(localStorage.getItem("token")).subscribe(
data => {
this.currentUserName = this.model.username;
localStorage.setItem("currentUserName", this.model.username);
this.model.username = "";
this.model.password = "";
},
error => console.log(error)
);
},
error => {
console.log("oh no");
console.log(error)
}
);
}
}
And then my LoginService
import { Injectable } from "#angular/core";
import { HttpClient } from '#angular/common/http';
import { HttpHeaders } from '#angular/common/http';
import { Observable } from "rxjs/index";
#Injectable()
export class LoginService {
token: string;
constructor (private http: HttpClient) {}
public sendCredential(model): Observable<String> {
const tokenUrlPreFlight = "http://localhost:8080/users/login/";
const httpOptions: {} = {
headers: new HttpHeaders({
'ContentType': 'application/json'
})
};
return this.http.post<String>(tokenUrlPreFlight, model, httpOptions);
}
public sendToken(token) {
const tokenUrlPostFlight = "http://localhost:8080/rest/users/";
console.log("Bearer " + token);
const httpOptions: {} = {
headers: new HttpHeaders({
'Authorization': 'Bearer ' + token
})
};
return this.http.get(tokenUrlPostFlight, httpOptions);
}
public logout(): void {
localStorage.setItem("token", "");
localStorage.setItem("currentUserName", "");
alert("You just logged out");
}
public checkLogin(): boolean {
if(localStorage.getItem("currentUserName") != null && localStorage.getItem("currentUserName") != "" && localStorage.getItem("token") != null && localStorage.getItem("token") != "") {
console.log(localStorage.getItem("currentUserName"));
console.log(localStorage.getItem("token"));
return true;
}
return false;
}
}
And now for the java. First here is my entry point:
import com.acb.app.configuration.JwtFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class App {
#Bean
public FilterRegistrationBean jwtFilter() {
final FilterRegistrationBean<JwtFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new JwtFilter());
filterRegistrationBean.addUrlPatterns("/rest/*");
return filterRegistrationBean;
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
My UserController.java
import com.acb.app.model.User;
import io.jsonwebtoken.*;
import com.acb.maki.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.ServletException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
#RestController
#RequestMapping("/users")
public class UserController {
#Autowired
private UserService userService;
#GetMapping("")
public List<User> userIndex() {
return userService.getAllUsers();
}
#GetMapping("{username}")
public Optional<User> getUserByUsername(#RequestBody String username) {
return userService.findByUsername(username);
}
#PostMapping("login")
public String login(#RequestBody Map<String, String> json) throws ServletException {
if(json.get("username") == null || json.get("password") == null) {
throw new ServletException("Please fill in username and password");
}
final String username = json.get("username");
final String password = json.get("password");
Optional<User> optionalUser = userService.findByUsername(username);
if(!optionalUser.isPresent()) {
throw new ServletException("Username not found");
}
User user = optionalUser.get();
if(!password.equals(user.getPassword())) {
throw new ServletException("Invalid login. Please check username and password");
}
final String response = Jwts.builder().setSubject(username).claim("roles", "user").setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256, "secretKey").compact();
final String jsonResponse = String.format("\"%s\"", response);
System.out.println(jsonResponse);
return jsonResponse;
}
#PostMapping(value="/register")
public User register(#RequestBody User user) {
return userService.save(user);
}
}
And last but not least my JwtFilter.java
import io.jsonwebtoken.*;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final String authHeader = request.getHeader("Authorization");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
filterChain.doFilter(servletRequest, servletResponse);
} else {
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw new ServletException("Missing or invalid authorization header");
}
final String token = authHeader.substring(7);
try {
final JwtParser jwtParser = Jwts.parser();
final Jws<Claims> claimsJws = jwtParser.setSigningKey("secretKey").parseClaimsJws(token);
final Claims claims = claimsJws.getBody();
request.setAttribute("claims", claims);
} catch (final SignatureException e) {
throw new ServletException("Invalid token.");
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
I am very aware of the bad practices here with comparing plain text passwords, etc. I'm just trying to get this to work for the time being. The token is correctly generated and returned. The token is also set correctly to local storage, but upon making the get request to the /rest/users route a 404 is returned. There are no errors on the java side.
So as I expected, I am indeed an idiot. As the user mentioned above my service maps to /users/ and what I needed is the protected version /rest/users. So next to my UserController I created UserResource.java which looks like so:
import com.acb.app.model.User;
import com.acb.app.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
#RequestMapping("/rest")
public class UserResource {
#Autowired
private UserService userService;
#RequestMapping("/users")
public List<User> findAllUsers() {
return userService.getAllUsers();
}
}
And this makes use of the JwtFilter and allows me to protect my routes. Hopefully this will be helpful to someone else.
How to access request headers in implementation of WriterInterceptor interface in JAX-RS?
context.getHeaders(); //This line gives a set of response headers(not request headers) in the WriterInterceptor implementation.
Complete code below:
public class GzipFilterWriterInterceptor implements WriterInterceptor {
private static final Logger LOG = LoggerFactory.getLogger(GzipFilterWriterInterceptor.class);
#Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
MultivaluedMap<String,Object> headers = context.getHeaders();
headers.add("Content-Encoding", "gzip");
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream));
context.proceed();
}
}
You can just inject HttpHeaders. It will be a thread-local proxy when it's injected, so it's thread safe.
#Context
private HttpHeaders headers;
It has methods
String getHeaderString(String name)
List<String> getRequestHeader(String name)
MultivaluedMap<String,String> getRequestHeaders()
UPDATE (test)
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
import java.util.logging.Logger;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
/**
* Run like any other JUnit test. Only one required dependency:
*
* <dependency>
* <groupId>org.glassfish.jersey.test-framework.providers</groupId>
* <artifactId>jersey-test-framework-provider-inmemory</artifactId>
* <scope>test</scope>
* <version>${jersey.version}</version>
* </dependency>
*/
public class HeadersTest extends JerseyTest {
#Path("hello")
public static class HelloResource {
#GET
public String get() {
return "Hello";
}
}
#Override
public ResourceConfig configure() {
return new ResourceConfig(HelloResource.class)
.register(HeaderWriter.class)
.register(new LoggingFilter(Logger.getAnonymousLogger(), true));
}
#Provider
public static class HeaderWriter implements WriterInterceptor {
#Context
private HttpHeaders headers;
#Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
context.proceed();
final String header = headers.getHeaderString("X-Request-Header");
context.getHeaders().add("X-Response-Header", header);
}
}
#Test
public void doit() {
final Response response = target("hello").request()
.header("X-Request-Header", "BooYah")
.get();
assertThat(response.getHeaderString("X-Response-Header"), is("BooYah"));
}
}
You can implement below code to ,see working example at http://jerseyexample-ravikant.rhcloud.com/rest/jws/say/Hello
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
#Provider
public class SecurityInterceptor implements ContainerRequestFilter, ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext reqCtx, ContainerResponseContext respCtx) throws IOException {
long startTime=0;
System.out.println("Adding ProcessingTime in response headers");
if(reqCtx.getHeaderString("startTime")!=null)
startTime = Long.parseLong(reqCtx.getHeaderString("startTime"));
respCtx.getHeaders().add("ProcessingTime",
String.valueOf(System.currentTimeMillis() - startTime) + " millisecs");
}
#Override
public void filter(ContainerRequestContext reqCtx) throws IOException {
System.out.println("Adding start time in request headers");
reqCtx.getHeaders().add("startTime", String.valueOf(System.currentTimeMillis()));
}
}
#Provider
public class GzipFilterWriterInterceptor implements WriterInterceptor
{
private static final Logger LOG = LoggerFactory.getLogger(GzipFilterWriterInterceptor.class);
// use a context injection
#Context
private HttpHeaders httpHeaders;
#Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException
{
MultivaluedMap<String,Object> headers = context.getHeaders();
headers.add("Content-Encoding", "gzip");
// do stuff with headers
if ("Basic Ym9iOnBhc3N3b3Jk".equals(httpHeaders.getRequestHeader("Authorization").get(0)))
{
//do stuff here, but be careful about the indexoutofbounds...
}
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream));
context.proceed();
}
}
The context injection will be injected per request, see the javadocs.
Probably not best solution, but you can have your interceptor implementing ReaderInterceptor. There you can get headers and save them in ThreadLocal variable so you can access then in WriterInterceptor
Also if you have annotation based configuration you can try to inject ContainerRequestContext with a #Context annotation
I am new to Camel and I am facing an issue while sending files to webservice via camel http.
I have a rest web service which consumes Multipart form data type content and accepts input as part of form data.
When I send file and form parameter via camel it gives me the following error at camel console:
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
org.apache.camel.component.http.HttpOperationFailedException: HTTP operation failed invoking http://localhost:8080/JAX_RS_Application/resource/restwb/upload with statusCode: 415
at org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException(HttpProducer.java:230)
at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:156)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:129)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:435)
at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:211)
at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:175)
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
The error i get on the server side console is as follows:
SEVERE: MessageBodyReader not found for media type=application/octet-stream, typ
e=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=clas
s org.glassfish.jersey.media.multipart.FormDataMultiPart.
The code snippet of the Rest web-service created via jersey is as follows:
import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/restwb")
public class FileResource {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public String uploadFile(#FormDataParam("username") String username,#FormDataParam("password") String password,#FormDataParam("upload") InputStream is) {
String output ="Hi "+username+" your password is "+password;
output=output+IOUtils.LINE_SEPARATOR +IOUtils.LINE_SEPARATOR;
output=output+"Output :"+IOUtils.LINE_SEPARATOR+"------------------------------------------------------------------------------"+IOUtils.LINE_SEPARATOR;
try {
output=output+IOUtils.toString(is)+IOUtils.LINE_SEPARATOR+IOUtils.LINE_SEPARATOR;
output=output+"==================================================================================================="+IOUtils.LINE_SEPARATOR+IOUtils.LINE_SEPARATOR;
System.out.println("Output :"+output);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return output;
}
}
And my Camel config is as follows:
import org.apache.camel.*;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.spi.Synchronization;
import org.apache.camel.spi.UnitOfWork;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.james.mime4j.message.Multipart;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
/**
* Created by Manish.Pillai on 7/16/2015.
*/
public class LoggingMain {
private static final Logger logger =Logger.getLogger(LoggingMain.class);
public static void main(String[] args) throws Exception{
CamelContext camelContext =new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file:C:\\temp?delay=5000&move=processed&moveFailed=error&antExclude=**/processed/**,**/error/**")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
exchange.getContext().getTypeConverterRegistry().addTypeConverter(HttpEntity.class,InputStream.class,new InputStreamToHttpEntityConvertor());
exchange.getOut().setBody(exchange.getIn().getBody(),HttpEntity.class);
}
})
.to("http://localhost:8080/JAX_RS_Application/resource/restwb/upload");
}
});
camelContext.getRestConfiguration();
camelContext.start();
Thread.sleep(5000);
camelContext.stop();
} catch (Exception e) {
logger.error(e.getMessage());
}
}
static class InputStreamToHttpEntityConvertor implements TypeConverter {
public boolean allowNull() {
return false;
}
public <T> T convertTo(Class<T> type, Object value) throws TypeConversionException {
Exchange exchange=(Exchange)value;
StringBody username = new StringBody("username", ContentType.MULTIPART_FORM_DATA);
StringBody password = new StringBody("password", ContentType.MULTIPART_FORM_DATA);
MultipartEntityBuilder multipartEntityBuilder=MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addPart("upload", new FileBody(exchange.getIn().getBody(File.class), ContentType.MULTIPART_FORM_DATA, (String) exchange.getIn().getHeader(Exchange.FILE_NAME)));
multipartEntityBuilder.addPart("username",username);
multipartEntityBuilder.addPart("password",password);
return (T)multipartEntityBuilder.build();
}
public <T> T convertTo(Class<T> aClass, Exchange exchange, Object o) throws TypeConversionException {
return convertTo(aClass,o);
}
public <T> T mandatoryConvertTo(Class<T> type, Object value) throws TypeConversionException, NoTypeConversionAvailableException {
return convertTo(type,value);
}
public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException, NoTypeConversionAvailableException {
return convertTo(type,value);
}
public <T> T tryConvertTo(Class<T> type, Object value) {
return convertTo(type,value);
}
public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) {
return convertTo(type,value);
}
}
}
Any leads would be helpful.
Well, there are several things that can be improved in your code.
First, since you are using a MultipartEntityBuilder, that means you're using Apache's HttpClient version 4.3+, so for best compatibility you should use Camel's HTTP4 component.
Third, in an example as small as this, you don't really need to use the converter, you can do something like this:
public class LoggingMain {
private static final Logger logger = Logger.getLogger(LoggingMain.class);
public static void main(String[] args) throws Exception {
CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file:C:\\temp?delay=5000&move=processed&moveFailed=error&antExclude=**/processed/**,**/error/**")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
StringBody username = new StringBody("username", ContentType.MULTIPART_FORM_DATA);
StringBody password = new StringBody("password", ContentType.MULTIPART_FORM_DATA);
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntityBuilder.addPart("username", username);
multipartEntityBuilder.addPart("password", password);
String filename = (String) exchange.getIn().getHeader(Exchange.FILE_NAME);
File file = exchange.getIn().getBody(File.class);
multipartEntityBuilder.addPart("upload", new FileBody(file, ContentType.MULTIPART_FORM_DATA, filename));
exchange.getIn().setBody(multipartEntityBuilder.build());
}
})
.to("http4://localhost:8080/JAX_RS_Application/resource/restwb/upload");
}
});
camelContext.getRestConfiguration();
camelContext.start();
Thread.sleep(5000);
camelContext.stop();
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
I hope this helps!
I want to add a client name parameter to my URL, so when i receive a link like :
http://localhost:8080/client1 i want to test if my client is present in database, if so i want that the client receive the content of my site like if he call :
http://localhost:8080/
I tried to do this with a wrapper like indicated here :
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ChangeURIPathFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(ChangeURIPathFilter.class);
RequestWrapper modifiedRequest = null;
#Override
public void init(FilterConfig filterConfig) throws ServletException {}
#Override
public void destroy() {}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String contextPath = ((HttpServletRequest) request).getContextPath();
String requestURI = httpRequest.getRequestURI();
modifiedRequest = new RequestWrapper(httpRequest, "/");
chain.doFilter(modifiedRequest, response);
}
class RequestWrapper extends HttpServletRequestWrapper {
private String originalValue;
public RequestWrapper(HttpServletRequest request) {
super(request);
}
#Override
public String getRequestURI() {
String originalURI = super.getRequestURI();
String s = super.getRequestURI();
if (StringUtils.equals(s, originalValue)) return originalValue
.replaceAll("client1", "");
else return s;
}
public RequestWrapper(HttpServletRequest request, String newValue) {
super(request);
this.originalValue = request.getRequestURI();
}
}
}
But all my tests failed. Can any one help me to resolve this ?
Thanks